Validate Email Address in C

We have been looking for ways to validate the email address (just make sure its correctly formed) and didn’t want to use the REGEXEC function so we thought we would try to find a method of doing it in straight C code against a passed string. We did find an example of how to do it for a ASCII based system but as the i5 is EBCDIC we had to change the program somewhat to make it work. We have not passed every type of email address through because there are so many, but using a set of addresses from our address book all passed and where we changed them to a format which should fail they did!

We have a EBCDIC to ASCII translator built which came in very handy as the string has to be parsed to ASCII to allow the allowed characters to be checked for (ASCII 32 – 127). We did look at simply converting the whole code to run against EBCDIC but the spread of the characters in numeric terms didn’t make that look easy! We could have converted each character back to EBCDIC as we needed to but this was a simpler route (yeah we sometimes take the easy route).

There are plenty of Conversion programs around so we don’t show it here. The rest of the code should run OK

int Check_Email_Addr(char *EM_Addr) {
int count = 0;
int i = 0;
char conv_buf[MAX_EMAIL_NAME];
char *c, *domain;
char *special_chars = "()<>@,;:\"[]";

/* The input is in EBCDIC so convert to ASCII first */
strcpy(conv_buf,EM_Addr);
EtoA(conv_buf);
/* convert the special chars to ASCII */
EtoA(special_chars);

for(c = conv_buf; *c; c++) {
   /* if '"' and beginning or previous is a '.' or '"' */
   if (*c == 34 && (c == conv_buf || *(c - 1) == 46 || *(c - 1) == 34)) {
      while (*++c) {
         /* if '"' break, End of name */
         if (*c == 34)
            break;
         /* if '' and ' ' */
         if (*c == 92 && (*++c == 32))
            continue;
         /* if not between ' ' & '~' */
         if (*c <= 32 || *c > 127)
            return 0;
         }
      /* if no more characters error */
      if (!*c++)
         return 0;
      /* found '@' */
      if (*c == 64)
         break;
      /* '.' required */
      if (*c != 46)
         return 0;
      continue;
      }
   if (*c == 64) {
      break;
      }
   /* make sure between ' ' && '~' */
   if (*c <= 32 || *c > 127) {
      return 0;
      }
   /* check special chars */
   if (strchr(special_chars, *c)) {
      return 0;
      }
   } /* end of for loop */
/* found '@' */
/* if at beginning or previous = '.' */
if (c == conv_buf || *(c - 1) == 46)
   return 0;
/* next we validate the domain portion */
/* if the next character is NULL */
/* need domain ! */
if (!*(domain = ++c))
   return 0;
do {
   /* if '.' */
   if (*c == 46) {
      /* if beginning or previous = '.' */
      if (c == domain || *(c - 1) == 46)
         return 0;
      /* count '.' need at least 1 */
      count++;
      }
   /* make sure between ' ' and '~' */
   if (*c <= 32 || *c >= 127)
      return 0;
   if (strchr(special_chars, *c))
      return 0;
   } while (*++c); /* while valid char */
return (count >= 1); /* return true if more than 1 '.' */
}

We have put lots of comments into the code to show how it works. The original idea came from a book called Secure Programming Cookbook from O’Reilly.
The biggest problem was converting the character set but taking the option to convert it all to ASCII first and then map the ASCII characters for the checking works well. We will review the REGEXEC method later to see if it is a better alternative but at this time we do have a working function.

Chris…

One thought on “Validate Email Address in C”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.