Logo Search packages:      
Sourcecode: nbsmtp version File versions  Download package

string_t* parse_mail ( string_t buffer,
int *  total_rcpts 
)

Finds some information we need from Message Headers and extract recipients into an array.

Parameters:
[out] buffer A pointer to the buffer that will hold the headers
[out] total_rcpts The total number of recipients
Returns:
Pointer to a string_t array holding all recipients

Definition at line 283 of file original.c.

References string::len, log_msg(), string::str, str_incr_space(), and str_init().

Referenced by main().

{
      char *toline, *endheader;
      char *headers[] = {"to: ", "cc: ", NULL}; /* Don't include bcc cause cc and bcc are the same to stracasestr */
      char tmp_rcpt[100];
      int i=0, cur_rcpt=0, cur_pos=0, cur_header, isemladdr=False, endheaders=False, c;
      int mem_arr_rcpts=5;
      string_t *rcpts;

      rcpts = malloc(mem_arr_rcpts*sizeof(string_t));

      /* Read msg from stdin and find end of headers */
      for (i=0; endheaders == False; i++)
      {
            if ( i >= buffer->len )
            {
                  str_incr_space(buffer, BUF_INC_HDR);
            }
            c = fgetc(stdin);
            buffer->str[i] = c;
            if (i>0 && buffer->str[i] == '\n' && buffer->str[i-1] == '\n')
            {
                  endheaders = True;
            }
            if (c == EOF)
            {
                  return NULL;
            }
      }

      endheader = (char *) &buffer->str[i-1];

      if(endheader == NULL)
      {
            return NULL;
      }


      for(cur_header=0; headers[cur_header] ; cur_header++)
      {
            toline = (char *)strcasestr(buffer->str, headers[cur_header]);

            if(toline)
            {
                  toline+=strlen(headers[cur_header]);
            }

            for(; toline && cur_rcpt<MAX_RCPTS; toline++)
            {
                  if (*toline=='\n' && *(toline-1)!=',' && *(toline-1)!=';' && *(toline-1)!=' ' && *(toline+1)!='\t')
                  {
                        break;
                  }

                  if (isemladdr == True && cur_pos >= rcpts[cur_rcpt].len-1)
                  {
                        str_incr_space(&rcpts[cur_rcpt], 10);
                  }

                  if (cur_rcpt >= mem_arr_rcpts-2)
                  {
                        rcpts = realloc(rcpts, (mem_arr_rcpts+5)*sizeof(string_t));
                        mem_arr_rcpts += 5;
                  }

                  if (isemladdr == False && cur_pos == 100)
                  {
                        /* Recipient really long, we assume rubbish and reset the counter */
                        cur_pos = 0;
                  }

                  switch(*toline)
                  {
                        case ',':
                        case ';':
                        case ' ':
                        case '\t':
                              if (isemladdr == True)
                              {
                                    rcpts[cur_rcpt++].str[cur_pos] = '\0';
                              }
                              cur_pos = 0;
                              isemladdr = False;
                              break;
                        case '<':
                        case '>':
                              break;
                        case '"':
                              do {
                                    toline++;
                              } while (*toline != '"');
                              break;
                        default:
                              if (*toline == '@')
                              {
                                    isemladdr = True;

                                    str_init(&rcpts[cur_rcpt],cur_pos+10);
                                    strncpy(rcpts[cur_rcpt].str,tmp_rcpt,cur_pos);

                                    if (cur_pos > 64)
                                    {
                                          log_msg(LOG_WARNING,"One address violates RFC2821," \
                                                      " local-part must be shorter"\
                                                      " than 65 characters");
                                    }
                              }

                              if (isemladdr==True)
                              {
                                    rcpts[cur_rcpt].str[cur_pos++] = *toline;
                              }
                              else
                              {
                                    tmp_rcpt[cur_pos++] = *toline;
                              }

                              break;
                  }
            }

            if(cur_pos>0)
            {
                  if (isemladdr == True)
                  {
                        rcpts[cur_rcpt++].str[cur_pos] = '\0';
                  }
                  cur_pos = 0;
                  isemladdr = False;
            }
      }

      if (cur_rcpt == 0)
      {
            log_msg(LOG_ERR,"No recipients found, exiting");
            return NULL;
      }

      *total_rcpts = cur_rcpt;

      return rcpts;
}


Generated by  Doxygen 1.6.0   Back to index