diff --git a/src/Parser.c b/src/Parser.c index aee970b..bef70af 100644 --- a/src/Parser.c +++ b/src/Parser.c @@ -25,14 +25,49 @@ #include #include +#include #include +#include + +/* Parse an extended localpart */ +static int +ParseUserLocalpart(char **str, char **out) +{ + char c; + char *start; + size_t length; + + if (!str || !out) + { + return 0; + } + /* An extended localpart contains every ASCII printable character, + * except an ':'. */ + start = *str; + while (isascii((c = (*(*str)++))) && c != ':' && c) + { + /* Do nothing */ + } + length = (size_t) (*str - start) -1; + if (c != ':' || length < 1) + { + *str = start; + return 0; + } + + *out = Malloc(length + 1); + memcpy(*out, start, length); + *out[length] = '\0'; + + + return 1; +} int ParseCommonID(char *str, CommonID *id) { char sigil; - char *servstart; if (!str || !id) { @@ -54,17 +89,17 @@ ParseCommonID(char *str, CommonID *id) return 0; } id->sigil = sigil; - - /* Find the position of a ':' if there is one. */ - if ((servstart = strchr(str, ':'))) - { - id->local = StrSubstr(str, 1, (char) (servstart - str)); - id->server = StrDuplicate(servstart + 1); - return 1; - } - /* Otherwise, just take the rest of the string. */ - id->local = StrDuplicate(str + 1) ; - id->server = NULL ; + switch(sigil) + { + case '@': + if (!ParseUserLocalpart(&str, &id->local)) + { + return 0; + } + /* TODO: Match whenever str is valid. */ + id->server = StrDuplicate(str); + break; + } return 1; }