/*
* Copyright (c) 2001, 2002, 2003, 2004, 2005 Netli, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ncnf_vr_constr.c,v 1.1 2005/05/26 12:08:19 vlm Exp $
*/
#include "headers.h"
#include "ncnf_int.h"
#include "ncnf_vr.h"
static void _vr_entity_free(void *);
static void _vr_rule_free(void *);
static int _vr_entity_cmpf(const void *ap, const void *bp);
static int _vr_entity_hashf(const void *ap);
static int
_vr_entity_cmpf(const void *ap, const void *bp) {
const struct vr_entity *a = ap;
const struct vr_entity *b = bp;
if(strcmp(a->type, b->type))
return -1;
if(a->name && b->name) {
if(strcmp(a->name, b->name) == 0)
return 0;
else
return -1;
}
if(a->name || b->name)
return -1;
return 0;
}
static int
_vr_entity_hashf(const void *ap) {
const struct vr_entity *a = ap;
return hashf_string(a->type);
}
static void
_vr_entity_free(void *p) {
struct vr_entity *e = (struct vr_entity *)p;
struct vr_rule *rule;
if(e->type) {
free(e->type);
e->type = NULL;
}
if(e->name) {
free(e->name);
e->name = NULL;
}
while(e->rules) {
rule = e->rules;
e->rules = rule->next;
_vr_rule_free(rule);
}
free(e);
}
static void
_vr_rule_free(void *p) {
struct vr_rule *r = (struct vr_rule *)p;
if(r) {
if(r->name) {
free(r->name);
r->name = NULL;
}
if(r->type && r->type->standalone) {
_vr_destroy_type(r->type);
}
free(r);
}
}
void
_vr_destroy_type(void *p) {
struct vr_type *ty = (struct vr_type *)p;
if(ty) {
if(ty->name) {
free(ty->name);
ty->name = NULL;
}
if(ty->regex) {
free(ty->regex);
ty->regex = NULL;
}
#ifdef HAVE_LIBSTRFUNC
sed_free(ty->regex_compiled);
#endif /* HAVE_LIBSTRFUNC */
free(ty);
}
}
struct vr_entity *
_vr_get_entity(struct vr_config *vc, char *type, char *name, int create) {
struct vr_entity static_entity;
struct vr_entity *e;
if(vc->entities) {
static_entity.type = type;
static_entity.name = name;
e = genhash_get(vc->entities, &static_entity);
if(e) return e;
if(name && create == 0) {
static_entity.name = NULL;
e = genhash_get(vc->entities, &static_entity);
if(e) return e;
}
if(create == 0)
return NULL;
e = (struct vr_entity *)calloc(1, sizeof(struct vr_entity));
if(e == NULL)
return NULL;
e->type = strdup(type);
if(e->type == NULL) {
_vr_entity_free(e);
return NULL;
}
if(name) {
e->name = strdup(name);
if(e->name == NULL) {
_vr_entity_free(e);
return NULL;
}
}
if(genhash_addunique(vc->entities, e, e)) {
_vr_entity_free(e);
return NULL;
}
} else {
if(create == 0)
return NULL;
vc->entities = genhash_new(
_vr_entity_cmpf,
_vr_entity_hashf,
NULL,
_vr_entity_free);
if(vc->entities)
return _vr_get_entity(vc, type, name, create);
else
return NULL;
}
return e;
}
struct vr_type * _vr_new_type(struct vr_config *vc, char *name, char *type, char *value, int line);
struct vr_type *
_vr_new_type(struct vr_config *vc, char *name, char *type, char *value, int line) {
struct vr_type *ty;
ty = (struct vr_type *)calloc(1, sizeof(struct vr_type));
if(ty == NULL)
return NULL;
ty->name = strdup(name);
if(ty->name == NULL) {
_vr_destroy_type(ty);
return NULL;
}
if(strcmp(type, VR_STR_TYPE) == 0) {
_vr_destroy_type(ty);
ty = NULL;
if(vc->types)
ty = genhash_get(vc->types, name);
if(ty == NULL) {
_ncnf_debug_print(1, "Can't find type \"%s\" for rule at line %d", value, line);
return NULL;
} else {
return ty;
}
} else if(strcmp(type, VR_STR_REGEX) == 0) {
#ifdef HAVE_LIBSTRFUNC
ty->regex = strdup(value);
if(ty->regex == NULL) {
_vr_destroy_type(ty);
return NULL;
}
ty->regex_compiled = sed_compile(value);
if(ty->regex_compiled == NULL) {
_ncnf_debug_print(1,
"Invalid regular expression \"%s\" at line %d",
value, line);
_vr_destroy_type(ty);
return NULL;
}
#else /* !HAVE_LIBSTRFUNC */
_ncnf_debug_print(1, "\"%s\" at line %d not supported: libstrfunc is not compiled in", type, line);
_vr_destroy_type(ty);
return NULL;
#endif /* HAVE_LIBSTRFUNC */
} else if(strcmp(type, VR_STR_RANGE) == 0) {
char *p = strchr(value, ':');
if(p == NULL) {
_ncnf_debug_print(1, "Range should be specified as min:max at line %d", line);
_vr_destroy_type(ty);
return NULL;
}
*p++ = '\0';
ty->range_defined = 1;
ty->range_start = atof(value);
ty->range_end = atof(p);
} else if(strcmp(type, VR_STR_IP) == 0) {
ty->ip_required = 1;
} else if(strcmp(type, VR_STR_IP_MASK) == 0) {
#ifdef HAVE_LIBSTRFUNC
ty->ip_mask_required = 1;
#else
_ncnf_debug_print(1, "\"%s\" at line %d not supported: libstrfunc is not compiled in", type, line);
_vr_destroy_type(ty);
return NULL;
#endif
} else if(strcmp(type, VR_STR_IP_MASKLEN) == 0) {
#ifdef HAVE_LIBSTRFUNC
ty->ip_masklen_required = 1;
#else
_ncnf_debug_print(1, "\"%s\" at line %d not supported: libstrfunc is not compiled in", type, line);
_vr_destroy_type(ty);
return NULL;
#endif
} else if(strcmp(type, VR_STR_IP_PORT) == 0) {
ty->ip_port_required = 1;
} else {
_ncnf_debug_print(1, "Unknown type: \"%s\" at line %d", type, line);
_vr_destroy_type(ty);
return NULL;
}
ty->standalone = 1;
return ty;
}
struct vr_type *
_vr_add_type(struct vr_config *vc, char *name, char *type, char *value, int line) {
struct vr_type *ty;
if(vc->types == NULL) {
vc->types = genhash_new(
cmpf_string, hashf_string,
NULL, _vr_destroy_type);
if(vc->types == NULL)
return NULL;
}
ty = _vr_new_type(vc, name ? name : value, type, value, line);
if(ty == NULL)
return NULL;
if(name == NULL)
return ty;
if(genhash_addunique(vc->types, ty->name, ty)) {
_vr_destroy_type(ty);
return NULL;
} else {
ty->standalone = 0;
}
return ty;
}
int
_vr_add_rule(int line, struct vr_config *vc, struct vr_entity *e,
char *mo, char *sm, char *ea, char *name, char *a, char *v) {
struct vr_rule *r, *prev;
r = (struct vr_rule *)calloc(1, sizeof(struct vr_rule));
if(r == NULL) {
_ncnf_debug_print(1, "Memory allocation error");
return -1;
}
/* mandatory | optional */
if(strcmp(mo, VR_STR_MANDATORY) == 0) {
r->mandatory = 1;
} else if(strcmp(mo, VR_STR_OPTIONAL) == 0) {
r->mandatory = 0;
} else {
_ncnf_debug_print(1, "%s or %s token expected at line %d",
VR_STR_MANDATORY, VR_STR_OPTIONAL, line);
goto fail;
}
/* single | multiple */
if(strcmp(sm, VR_STR_SINGLE) == 0) {
r->multiple = 0;
} else if(strcmp(sm, VR_STR_MULTIPLE) == 0) {
r->multiple = 1;
} else {
_ncnf_debug_print(1, "%s or %s token expected at line %d",
VR_STR_SINGLE, VR_STR_MULTIPLE, line);
goto fail;
}
/* entity | attribute | ... */
if(strcmp(ea, VR_STR_ATTRIBUTE) == 0) {
r->vr_obj_class = VR_CLASS_ATTRIBUTE;
} else if(strcmp(ea, VR_STR_ENTITY) == 0) {
r->vr_obj_class = VR_CLASS_ENTITY;
} else if(strcmp(ea, VR_STR_REFERENCE) == 0) {
r->vr_obj_class = VR_CLASS_REFERENCE;
} else if(strcmp(ea, VR_STR_ATTACH) == 0) {
r->vr_obj_class = VR_CLASS_ATTACHMENT;
} else {
_ncnf_debug_print(1, "%s or %s token expected at line %d",
VR_STR_ENTITY, VR_STR_ATTRIBUTE, line);
goto fail;
}
r->name = strdup(name);
if(r->name == NULL)
goto fail;
if(strcmp(r->name, VR_STR_VALIDATOR_ENTITY) == 0)
r->_entity_reference = 1;
if(a) {
r->type = _vr_add_type(vc, NULL, a, v, line);
if(r->type == NULL)
goto fail;
}
prev = e->rules;
while(prev && prev->next)
prev = prev->next;
if(prev)
prev->next = r;
else
e->rules = r;
return 0;
fail:
_vr_rule_free(r);
return -1;
}
syntax highlighted by Code2HTML, v. 0.9.1