/*
* Copyright (c) 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: validdomain.c,v 1.5 2006/12/25 20:37:01 ca Exp $")
#include "sm/assert.h"
#include "sm/error.h"
#include "sm/ctype.h"
#include "sm/net.h"
#include "sm/rfc2821.h"
#include "sm/str.h"
#include "sm/misc.h"
/*
** VALIDDOMAIN -- check whether a domain is syntactically valid
**
** Parameters:
** str -- string that stores domain
** flags -- flags to influence checks
**
** Returns:
** true iff domain is syntactically valid
*/
bool
validdomain(sm_str_P str, uint flags)
{
uint i, len, beginsub;
uchar ch, lastch;
if (NULL == str)
return false;
len = sm_str_getlen(str);
if (0 == len)
return false;
ch = sm_str_rd_elem(str, 0);
if (ch == '[') {
sm_ret_T ret;
char *begin, *end;
ipv4_T ipv4;
begin = (char *) sm_str_getdata(str);
if (NULL == begin)
return true;
ret = sm_inet_a2ipv4(begin, &end, &ipv4);
return sm_is_success(ret);
}
beginsub = 0;
do {
/*
** Domain = (sub-domain 1*("." sub-domain)) / address-literal
** sub-domain = Let-dig [Ldh-str]
** Let-dig = ALPHA / DIGIT
** Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
*/
ch = sm_str_rd_elem(str, beginsub);
if (!ISALNUM(ch))
return false;
for (i = beginsub; i < len; ++i) {
lastch = ch;
ch = sm_str_rd_elem(str, i);
if ('.' == ch) {
if (!ISALNUM(lastch))
return false;
beginsub = i + 1;
break;
}
if (!(ISALNUM(ch) || ch == '-'
|| (HAS_R2821(flags, R2821__) && ch == '_')))
return false;
}
SM_ASSERT(i >= len || '.' == ch);
if ('.' == ch && beginsub >= len)
return !HAS_R2821(flags, R2821_NO_TRLDOT);
} while (i < len);
if (!ISALNUM(ch)) {
if ('.' == ch)
return !HAS_R2821(flags, R2821_NO_TRLDOT);
return false;
}
return true;
}
syntax highlighted by Code2HTML, v. 0.9.1