This is the mail archive of the cluster-cvs@sourceware.org mailing list for the cluster.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cluster: STABLE3 - config: Add rng2ldif utility for LDIF maintenance


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=6ba6404b0725fc61bd7df34734caa6b204ce1f28
Commit:        6ba6404b0725fc61bd7df34734caa6b204ce1f28
Parent:        d3d6c6ff20bf149507d47301a87033fb2af89bfd
Author:        Lon Hohberger <lhh@redhat.com>
AuthorDate:    Tue Sep 8 13:18:31 2009 -0400
Committer:     Fabio M. Di Nitto <fdinitto@redhat.com>
CommitterDate: Wed Sep 9 10:57:09 2009 +0200

config: Add rng2ldif utility for LDIF maintenance

* Converts cluster.rng into 99cluster.ldif + ldap-base.csv
* NOT an installed target at this point; used only for
  config schema maintenance
* NOT automatically built at this point
* Sample ldif-update target included in Makefile

Signed-off-by: Lon Hohberger <lhh@redhat.com>
---
 config/tools/ldap/rng2ldif/Makefile     |   46 +++++
 config/tools/ldap/rng2ldif/debug.h      |   10 +
 config/tools/ldap/rng2ldif/genclass.c   |  102 ++++++++++
 config/tools/ldap/rng2ldif/ldaptypes.c  |   53 ++++++
 config/tools/ldap/rng2ldif/ldaptypes.h  |    8 +
 config/tools/ldap/rng2ldif/name.c       |   58 ++++++
 config/tools/ldap/rng2ldif/name.h       |    6 +
 config/tools/ldap/rng2ldif/rng2ldif.c   |  212 +++++++++++++++++++++
 config/tools/ldap/rng2ldif/tree.c       |  311 +++++++++++++++++++++++++++++++
 config/tools/ldap/rng2ldif/tree.h       |   38 ++++
 config/tools/ldap/rng2ldif/value-list.c |  192 +++++++++++++++++++
 config/tools/ldap/rng2ldif/value-list.h |   29 +++
 config/tools/ldap/rng2ldif/zalloc.c     |   23 +++
 config/tools/ldap/rng2ldif/zalloc.h     |    6 +
 14 files changed, 1094 insertions(+), 0 deletions(-)

diff --git a/config/tools/ldap/rng2ldif/Makefile b/config/tools/ldap/rng2ldif/Makefile
new file mode 100644
index 0000000..5192780
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/Makefile
@@ -0,0 +1,46 @@
+TARGET1= rng2ldif
+TARGET2= genclass
+
+all: ${TARGET1} ${TARGET2}
+
+include ../../../../make/defines.mk
+include $(OBJDIR)/make/cobj.mk
+include $(OBJDIR)/make/clean.mk
+include $(OBJDIR)/make/install.mk
+include $(OBJDIR)/make/uninstall.mk
+
+CFLAGS += -D_GNU_SOURCE
+CFLAGS += -I. -I${incdir}
+CFLAGS += `xml2-config --cflags`
+
+LDFLAGS += `xml2-config --libs`
+LDFLAGS += -L${libdir}
+
+OBJS1=  rng2ldif.o \
+	tree.o
+
+OBJS2=  genclass.o
+
+SHAREDOBJS= zalloc.o \
+	    value-list.o \
+	    ldaptypes.o \
+	    name.o
+
+${TARGET1}: ${SHAREDOBJS} ${OBJS1}
+	$(CC) -o $@ $^ $(EXTRA_LDFLAGS) $(LDFLAGS)
+
+${TARGET2}: ${SHAREDOBJS} ${OBJS2}
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+ldif-update: all ../../../plugins/ldap/ldap-base.csv
+	make -C ../../xml cluster.rng
+	./rng2ldif ../../xml/cluster.rng \
+		../../../plugins/ldap/ldap-base.csv \
+		../../../plugins/ldap/99cluster.ldif
+	
+
+clean: generalclean
+
+-include $(OBJS1:.o=.d)
+-include $(OBJS2:.o=.d)
+-include $(SHAREDOBJS:.o=.d)
diff --git a/config/tools/ldap/rng2ldif/debug.h b/config/tools/ldap/rng2ldif/debug.h
new file mode 100644
index 0000000..907e096
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/debug.h
@@ -0,0 +1,10 @@
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+#ifdef DEBUG
+#define dbg_printf printf
+#else
+#define dbg_printf(args...)
+#endif
+
+#endif
diff --git a/config/tools/ldap/rng2ldif/genclass.c b/config/tools/ldap/rng2ldif/genclass.c
new file mode 100644
index 0000000..7607714
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/genclass.c
@@ -0,0 +1,102 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include "value-list.h"
+#include "tree.h"
+
+
+static void
+id_gen_object_struct(struct idinfo *oi, FILE *fp)
+{
+	struct idval *v;
+
+	fprintf(fp, "struct objectclasses\n");
+	fprintf(fp, "{\n");
+	fprintf(fp, "\tchar *name;\n");
+	fprintf(fp, "\tchar *class;\n");
+	fprintf(fp, "} objectclasses[] = \n");
+	fprintf(fp, "{\n");
+
+	for (v = oi->head; v->next; v = v->next) {
+		if (v->type != OBJ)
+			continue;
+		fprintf(fp, "\t{ \"%s\", \"%s\" }, \n",
+			v->rawname, v->name);
+	}
+
+	fprintf(fp, "\t{ \"%s\", \"%s\" }\n};\n",
+		v->rawname, v->name);
+}
+
+
+static int
+write_class_struct(char *csv, char *arg, struct idinfo *ids)
+{
+	char filename[4096];
+	FILE *out = NULL;
+	int fd = -1;
+
+	if (!strcmp(arg, "-")) {
+		out = stdout;
+	} else {
+		snprintf(filename, sizeof(filename), "%s.XXXXXX", arg);
+		fd = mkstemp(filename);
+		if (fd < 0) {
+			perror("mkstemp");
+			return -1;
+		}
+
+		out = fdopen(fd, "w");
+		if (out == NULL) {
+			perror("fdopen");
+			close(fd);
+			return -1;
+		}
+	}
+
+	fprintf(out, "/* Begin autogenerated class struct from %s */\n", csv);
+	id_gen_object_struct(ids, out);
+	fprintf(out, "/* End autogenerated class struct */\n");
+
+	fflush(out);
+
+	if (fd >= 0) {
+		fsync(fd);
+		fclose(out);
+		close(fd);
+		rename(filename, arg);
+	}
+
+	return 0;
+}
+
+
+int
+main(int argc, char **argv)
+{
+	struct idinfo info;
+
+	memset(&info, 0, sizeof(info));
+
+	if (argc < 3) {
+		printf("Translate csv -> C structure\n"
+		       "file for future reuse of IDs\n");
+		printf("Usage: %s file.csv output.c\n",
+		       argv[0]);
+		return 1;
+	}
+
+	if (id_readfile(&info, argv[1]) < 0) {
+		printf("Can't read %s\n", argv[1]);
+		return 1;
+	}
+
+	write_class_struct(argv[1], argv[2], &info);
+
+	return 0;
+}
diff --git a/config/tools/ldap/rng2ldif/ldaptypes.c b/config/tools/ldap/rng2ldif/ldaptypes.c
new file mode 100644
index 0000000..beb0de9
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/ldaptypes.c
@@ -0,0 +1,53 @@
+#include <stdio.h>
+#include <string.h>
+#include "ldaptypes.h"
+#include "debug.h"
+
+struct type_entry {
+	const char *rng_name;
+	const char *ldap_equality;
+	const char *ldap_syntax;
+};
+
+
+struct type_entry type_table[] = {
+{ "boolean",	"booleanMatch",		"1.3.6.1.4.1.1466.115.121.1.7" },
+{ "integer",	"integerMatch",		"1.3.6.1.4.1.1466.115.121.1.27" },
+{ "positiveInteger",	"integerMatch",	"1.3.6.1.4.1.1466.115.121.1.27" },
+{ "nonNegativeInteger",	"integerMatch",	"1.3.6.1.4.1.1466.115.121.1.27" },
+{ "string",	"caseExactIA5Match",	"1.3.6.1.4.1.1466.115.121.1.26" },
+{ "ID",		"caseExactIA5Match",	"1.3.6.1.4.1.1466.115.121.1.26" },
+{ NULL,		"caseExactIA5Match",	"1.3.6.1.4.1.1466.115.121.1.26" } };
+
+
+void
+find_ldap_type_info(const char *name,
+		    char **equality,
+		    char **syntax)
+{
+	int x;
+
+	for (x = 0; type_table[x].rng_name != NULL; x++) 
+		if (!strcasecmp(name, type_table[x].rng_name))
+			break;
+	dbg_printf("%s @ index %d\n", name, x);
+
+	*equality = (char *)type_table[x].ldap_equality;
+	*syntax = (char *)type_table[x].ldap_syntax;
+}
+
+
+#ifdef STANDALONE
+#include <stdio.h>
+int
+main(int argc, char **argv)
+{
+	char *eq, *syn;
+
+	find_ldap_type_info(argv[1], &eq, &syn);
+
+	printf("EQUALITY %s\nSYNTAX %s\n", eq, syn);
+
+	return 0;
+}
+#endif
diff --git a/config/tools/ldap/rng2ldif/ldaptypes.h b/config/tools/ldap/rng2ldif/ldaptypes.h
new file mode 100644
index 0000000..1546cf3
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/ldaptypes.h
@@ -0,0 +1,8 @@
+#ifndef _LDAPTYPES_H
+#define _LDAPTYPES_H
+
+void find_ldap_type_info(const char *name,
+			 char **equality,
+			 char **syntax);
+
+#endif
diff --git a/config/tools/ldap/rng2ldif/name.c b/config/tools/ldap/rng2ldif/name.c
new file mode 100644
index 0000000..8cc5ef7
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/name.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include "name.h"
+#include "zalloc.h"
+
+char *
+normalize_name(const char *name)
+{
+	char *ret_val;
+	int size = 4, x;
+
+	if (!strcasecmp(name, "name")) {
+		ret_val = strdup(name);
+		assert(ret_val!=NULL);
+		goto out;
+	}
+
+	size = strlen(name)+5;
+	ret_val = zalloc(size); /* 1 byte for null, 4 for rhcs */
+	if (!ret_val)
+		return NULL;
+
+	snprintf(ret_val, size, "rhcs%s", name);
+
+out:
+	for (x = 0; x < 4; x++)
+		ret_val[x] |= 32;
+	if (ret_val[4] == '_')
+		ret_val[4] = '-';
+	else
+		ret_val[4] &= ~32;
+	for (x = 5; x < size; x++) {
+		if (ret_val[x] == '_') {
+			ret_val[x] = '-';
+		}
+	}
+
+	return ret_val;
+}
+
+#ifdef STANDALONE
+int
+main(int argc, char **argv)
+{
+	char *val;
+	if (argc < 2)
+		return -1;
+
+	val = normalize_name(argv[1]);
+	if (!val) 
+		fprintf(stderr, "oops\n");
+	printf("%s\n", val);
+	free(val);
+	return 0;
+}
+#endif
diff --git a/config/tools/ldap/rng2ldif/name.h b/config/tools/ldap/rng2ldif/name.h
new file mode 100644
index 0000000..a332b45
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/name.h
@@ -0,0 +1,6 @@
+#ifndef _NAME_H
+#define _NAME_H
+
+char *normalize_name(const char *name);
+
+#endif
diff --git a/config/tools/ldap/rng2ldif/rng2ldif.c b/config/tools/ldap/rng2ldif/rng2ldif.c
new file mode 100644
index 0000000..39e2cbc
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/rng2ldif.c
@@ -0,0 +1,212 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include "value-list.h"
+#include "tree.h"
+
+
+struct faux_list {
+	struct faux_list *next;
+};
+
+
+static void __attribute__((noinline))
+reverse(struct faux_list **list)
+{
+	struct faux_list *node = NULL;
+	struct faux_list *newlist = NULL;
+
+	if (!list || (*list == NULL))
+		return;
+
+	while ((*list) != NULL) {
+		node = *list;
+		*list = node->next;
+		node->next = newlist;
+		newlist = node;
+	}
+	*list = node;
+}
+
+
+static int
+print_attr_node(FILE *fp, struct ldap_attr_node *node)
+{
+	if (!node)
+		return -1;
+	if (!fp)
+		fp = stdout;
+
+	if (!strcasecmp(node->name, "name")) {
+		/* Don't print 'name' out as an attr. */
+		return 0;
+	}
+
+	fprintf(fp, "attributeTypes: (\n");
+	fprintf(fp, "  1.3.6.1.4.1.2312.8.1.1.%d NAME '%s'\n",
+		node->idval->value, node->name);
+	fprintf(fp, "  EQUALITY %s\n", node->ldap_equality);
+	fprintf(fp, "  SYNTAX %s\n", node->ldap_syntax);
+	fprintf(fp, "  SINGLE-VALUE\n  )\n");
+	return 0;
+}
+
+
+static int
+print_obj_node(FILE *fp, struct ldap_object_node *node)
+{
+	struct ldap_attr_meta_node *n;
+	const char *cmt = "";
+
+	if (!node)
+		return -1;
+	if (!fp)
+		fp = stdout;
+
+	if (!node->required_attrs && !node->optional_attrs) {
+		cmt = "#";
+		fprintf(fp, "### Placeholder for %s\n", node->name);
+		fprintf(fp,
+			"### This object class currently has no attributes\n");
+	}
+
+	fprintf(fp, "%sobjectClasses: (\n", cmt);
+	fprintf(fp, "%s     1.3.6.1.4.1.2312.8.1.2.%d NAME '%s' SUP top STRUCTURAL\n", cmt, node->idval->value, node->name);
+
+	if (node->required_attrs) {
+		fprintf(fp, "%s     MUST ( ", cmt);
+		for (n = node->required_attrs; n->next != NULL; n = n->next)
+			fprintf(fp, "%s $ ", n->node->name);
+		fprintf(fp, "%s )\n", n->node->name);
+	}
+	if (node->optional_attrs) {
+		fprintf(fp, "%s     MAY ( ", cmt);
+		for (n = node->optional_attrs; n->next != NULL; n = n->next)
+			fprintf(fp, "%s $ ", n->node->name);
+		fprintf(fp, "%s )\n", n->node->name);
+	}
+	fprintf(fp, "%s   )\n", cmt);
+	return 0;
+}
+
+
+static xmlDocPtr 
+open_relaxng(const char *filename)
+{
+	xmlDocPtr p;
+	xmlNodePtr n;
+
+	p = xmlParseFile(filename);
+	if (!p) {
+		printf("Failed to parse %s\n", filename);
+	}
+
+	n = xmlDocGetRootElement(p);
+	if (xmlStrcmp(n->name, (xmlChar *)"grammar")) {
+		printf("%s is not a relaxng grammar\n", filename);
+		xmlFreeDoc(p);
+		return NULL;
+	}
+
+	return p;
+}
+
+
+static int
+write_ldap_schema(const char *rng, const char *arg,
+		  struct ldap_attr_node *attrs,
+		  struct ldap_object_node *objs)
+{
+	struct ldap_attr_node *attr = NULL;
+	struct ldap_object_node *obj = NULL;
+	char filename[4096];
+	FILE *out_ldap = NULL;
+	int fd = -1;
+
+	if (!strcmp(arg, "-")) {
+		out_ldap = stdout;
+	} else {
+		snprintf(filename, sizeof(filename), "%s.XXXXXX", arg);
+		fd = mkstemp(filename);
+		if (fd < 0) {
+			perror("mkstemp");
+			return -1;
+		}
+
+		out_ldap = fdopen(fd, "w");
+		if (out_ldap == NULL) {
+			perror("fdopen");
+			close(fd);
+			return -1;
+		}
+	}
+
+	fprintf(out_ldap, "# Auto-generated from %s\n", rng);
+	fprintf(out_ldap, "dn: cn=schema\n");
+
+	for (attr = attrs; attr; attr = attr->next)
+		print_attr_node(out_ldap, attr);
+	for (obj = objs; obj; obj= obj->next)
+		print_obj_node(out_ldap, obj);
+
+	fflush(out_ldap);
+
+	if (fd >= 0) {
+		fsync(fd);
+		fclose(out_ldap);
+		close(fd);
+		rename(filename, arg);
+	}
+
+	return 0;
+}
+
+
+int
+main(int argc, char **argv)
+{
+	struct ldap_attr_node *attrs = NULL;
+	struct ldap_object_node *objs = NULL;
+	struct idinfo info;
+	xmlDocPtr doc;
+
+	memset(&info, 0, sizeof(info));
+
+	if (argc < 4) {
+		printf("Translate cluster RelaxNG -> LDIF schema and update\n"
+		       "global .csv file for future reuse of IDs\n");
+		printf("Usage: %s cluster.rng ldap-base.csv cluster.ldif\n",
+		       argv[0]);
+		return 1;
+	}
+
+	doc = open_relaxng(argv[1]);
+       	if (doc == NULL) {
+		printf("Cannot continue\n");
+		return 1;
+	}
+
+	if (id_readfile(&info, argv[2]) < 0) {
+		printf("Can't read %s\n", argv[2]);
+		return 1;
+	}
+
+	if (find_objects(xmlDocGetRootElement(doc),
+			 &objs, &attrs, &info) < 0)
+		return 1;
+
+	reverse((struct faux_list **)&attrs);
+	reverse((struct faux_list **)&objs);
+
+	if (write_ldap_schema(argv[1], argv[3], attrs, objs) < 0)
+		return -1;
+
+	id_writefile(&info, argv[2]);
+
+	return 0;
+}
diff --git a/config/tools/ldap/rng2ldif/tree.c b/config/tools/ldap/rng2ldif/tree.c
new file mode 100644
index 0000000..a6e0b46
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/tree.c
@@ -0,0 +1,311 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+
+#include "zalloc.h"
+#include "value-list.h"
+#include "tree.h"
+#include "name.h"
+#include "ldaptypes.h"
+#include "debug.h"
+
+
+static struct ldap_attr_node *
+find_attr(struct ldap_attr_node *attrs, const char *name)
+{
+	struct ldap_attr_node *n;
+
+	for (n = attrs; n; n = n->next) {
+		if (!strcmp(n->name, name))
+			return n;
+	}
+	return NULL;
+}
+
+
+static struct ldap_attr_meta_node *
+find_meta_attr(struct ldap_attr_meta_node *metas, struct ldap_attr_node *attr)
+{
+	struct ldap_attr_meta_node *n;
+
+	for (n = metas; n; n = n->next) {
+		if (n->node == attr)
+			return n;
+	}
+	return NULL;
+}
+
+
+static int
+find_data_match_fn(xmlNodePtr curr_node, char **match_fn, char **ldap_syntax)
+{
+	xmlNodePtr n = NULL;
+	char *type = NULL;
+	int need_free = 1;
+
+	for (n = curr_node; n; n = n->next) {
+		if (!n->name ||
+    		    strcasecmp((char *)n->name, "data"))
+			continue;
+		break;	
+	}
+
+	if (n)
+		type = (char *)xmlGetProp(n, (xmlChar *)"type");
+
+	dbg_printf("type %s\n", type);
+
+	if (!type) {
+		type = (char *)"string";
+		need_free = 0;
+	}
+
+	find_ldap_type_info(type, match_fn, ldap_syntax);
+	
+	if (need_free)
+		xmlFree(type);
+
+	return 1;
+}
+
+
+static struct ldap_attr_node *
+get_attr(xmlNodePtr curr_node, struct ldap_attr_node **attrs,
+	 struct idinfo *ids)
+{
+	struct ldap_attr_node *n;
+	struct idval *v;
+	char *name, *normalized;
+
+	name = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
+	normalized = normalize_name((const char *)name);
+
+	n = find_attr(*attrs, normalized);
+	if (n) {
+		free(normalized);
+		return n;
+	}
+
+	n = zalloc(sizeof(*n));
+
+	v = id_find(ids, normalized, ATTR, 0);
+	if (!v) {
+		v = zalloc(sizeof(*v));
+		v->name = normalized;
+		v->type = ATTR;
+		v->rawname = (char *)name;
+		id_insert(ids, v);
+	} else {
+		free(normalized);
+	}
+
+	n->idval = v;
+	n->name = n->idval->name;
+
+	dbg_printf("Lookin for data type for %s\n", n->name);
+	find_data_match_fn(curr_node->xmlChildrenNode, &n->ldap_equality,
+			   &n->ldap_syntax);
+
+	n->next = *attrs;
+	*attrs = n;
+
+	return n;
+}
+
+
+static struct ldap_object_node *
+find_obj(struct ldap_object_node *objs, const char *name)
+{
+	struct ldap_object_node *n;
+
+	for (n = objs; n; n = n->next) {
+		if (!strcmp(n->name, name))
+			return n;
+	}
+	return NULL;
+}
+
+
+
+static int
+find_optional_attributes(xmlNodePtr curr_node, int in_block,
+			 struct ldap_object_node *curr_obj,
+			 struct ldap_attr_node **attrs,
+			 struct idinfo *ids)
+{
+	xmlNodePtr node;
+	struct ldap_attr_node *attr;
+	struct ldap_attr_meta_node *n;
+
+	if (!curr_node || (curr_node->type == XML_ELEMENT_NODE &&
+	    (curr_node->name && !strcasecmp((char *)curr_node->name, "element")))) {
+		return 0;
+	}
+
+	dbg_printf("lookin for optionals\n");
+
+	for (node = curr_node; node; node = node->next) {
+		if (node->type != XML_ELEMENT_NODE)
+			continue;
+		if (!strcasecmp((char *)node->name, "choice")) {
+			find_optional_attributes(node->xmlChildrenNode, 1,
+						 curr_obj,
+						 attrs, ids);
+			continue;
+		}
+		if (!strcasecmp((char *)node->name, "group")) {
+			find_optional_attributes(node->xmlChildrenNode, 1,
+						 curr_obj,
+						 attrs, ids);
+			continue;
+		}
+		if (!strcasecmp((char *)node->name, "optional")) {
+			find_optional_attributes(node->xmlChildrenNode, 1,
+						 curr_obj,
+						 attrs, ids);
+			continue;
+		}
+
+		if (!node->name || strcmp((char *)node->name,
+			    "attribute")) {
+			continue;
+		}
+
+		if (!in_block)
+			continue;
+
+		attr = get_attr(node, attrs, ids);
+		n = zalloc(sizeof(*n));
+
+		dbg_printf("opt attr '%s'\n", attr->idval->name);
+
+		if (find_meta_attr(curr_obj->required_attrs,
+				   attr)) {
+			dbg_printf("skipping dup attr\n");
+			continue;
+		}
+		if (find_meta_attr(curr_obj->optional_attrs,
+				   attr)) {
+			dbg_printf("skipping dup attr on optional list\n");
+			continue;
+		}
+
+		n->node = attr;
+		n->next = curr_obj->optional_attrs;
+		curr_obj->optional_attrs = n;
+	}
+	return 0;
+}
+
+
+static int
+find_required_attributes(xmlNodePtr curr_node,
+			 struct ldap_object_node *curr_obj,
+			 struct ldap_attr_node **attrs,
+			 struct idinfo *ids)
+{
+	xmlNodePtr node;
+	struct ldap_attr_node *attr;
+	struct ldap_attr_meta_node *n;
+
+	dbg_printf("lookin for required\n");
+
+	for (node = curr_node; node; node = node->next) {
+		if (node->type != XML_ELEMENT_NODE)
+			continue;
+		if (xmlStrcmp(node->name, (xmlChar *)"attribute"))
+			continue;
+
+		attr = get_attr(node, attrs, ids);
+		n = zalloc(sizeof(*n));
+
+		dbg_printf("req attr '%s'\n", attr->idval->name);
+
+		if (find_meta_attr(curr_obj->required_attrs,
+				   attr)) {
+			dbg_printf("skipping dup attr\n");
+			continue;
+		}
+		if (find_meta_attr(curr_obj->optional_attrs,
+				   attr)) {
+			dbg_printf("skipping dup attr on optional list\n");
+			continue;
+		}
+
+		n->node = attr;
+		n->next = curr_obj->required_attrs;
+		curr_obj->required_attrs = n;
+	}
+	return 0;
+}
+
+
+static void
+parse_element_tag(xmlNodePtr curr_node,
+		  struct ldap_object_node **objs,
+		  struct ldap_attr_node **attrs,
+		  struct idinfo *ids)
+{
+	struct ldap_object_node *obj;
+	char *n, *normalized;
+	struct idval *v;
+	
+	dbg_printf("Trying to parse element tag\n");
+	n = (char *)xmlGetProp(curr_node, (xmlChar *)"name");
+	normalized = normalize_name(n);
+	v = id_find(ids, normalized, OBJ, 0);
+
+	if (!v) {
+		v = zalloc(sizeof(*v));
+		v->name = normalized;
+		v->rawname = n;
+		v->type = OBJ;
+		id_insert(ids, v);
+	}
+
+	obj = find_obj(*objs, v->name);
+
+	if (!obj) {
+		obj = zalloc(sizeof(*obj));
+		obj->name = v->name;
+		obj->idval = v;
+		obj->next = *objs;
+		*objs = obj;
+		dbg_printf("New object class %s \n",obj->name);
+	}
+
+	find_optional_attributes(curr_node->xmlChildrenNode, 0,
+				 obj, attrs, ids);
+	find_required_attributes(curr_node->xmlChildrenNode,
+				 obj, attrs, ids);
+}
+
+
+int
+find_objects(xmlNodePtr curr_node,
+	     struct ldap_object_node **objs,
+	     struct ldap_attr_node **attrs,
+	     struct idinfo *ids)
+{
+	//xmlNodePtr node;
+
+	if (!curr_node)
+		return 0;
+
+	for (; curr_node; curr_node = curr_node->next) {
+		if (curr_node->type != XML_ELEMENT_NODE)
+			continue;
+		if (!strcasecmp((char *)curr_node->name, "element")) {
+			parse_element_tag(curr_node, objs, attrs, ids);
+		} else {
+			dbg_printf("Descend on %s\n", curr_node->name);
+		}
+		find_objects(curr_node->xmlChildrenNode,
+			     objs, attrs, ids);
+
+	}
+
+	return 0;
+}
diff --git a/config/tools/ldap/rng2ldif/tree.h b/config/tools/ldap/rng2ldif/tree.h
new file mode 100644
index 0000000..098f4b6
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/tree.h
@@ -0,0 +1,38 @@
+#ifndef _TREE_H
+#define _TREE_H
+
+struct ldap_attr_list {
+	struct ldap_attr_node *head, *tail;
+};
+
+struct ldap_attr_node {
+	struct ldap_attr_node *next;
+	char *name; /* self->idval->name; do not free() */
+	char *desc;
+	char *ldap_equality;
+	char *ldap_syntax;
+	struct idval *idval;
+};
+
+struct ldap_attr_meta_node {
+	struct ldap_attr_meta_node *next;
+	struct ldap_attr_node *node;
+};
+
+struct ldap_object_node {
+	struct ldap_object_node *next;
+	char *name; /* self->idval->name; do not free() */
+	char *desc;
+	struct idval *idval;
+	struct ldap_attr_meta_node *optional_attrs;
+	struct ldap_attr_meta_node *required_attrs;
+};
+
+int
+find_objects(xmlNodePtr curr_node,
+	     struct ldap_object_node **objs,
+	     struct ldap_attr_node **attrs,
+	     struct idinfo *ids);
+
+
+#endif
diff --git a/config/tools/ldap/rng2ldif/value-list.c b/config/tools/ldap/rng2ldif/value-list.c
new file mode 100644
index 0000000..d8b0e84
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/value-list.c
@@ -0,0 +1,192 @@
+/** License: GPLv2 */
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+#include "value-list.h"
+#include "zalloc.h"
+
+void
+id_insert(struct idinfo *i, struct idval *v)
+{
+	if (v->type == ATTR) {
+		if (v->value > i->max_attr)
+			i->max_attr = v->value;
+		if (!v->value)
+			v->value = ++i->max_attr;
+	} else /* if type == OBJ */ {
+		if (v->value > i->max_obj)
+			i->max_obj = v->value;
+		if (!v->value)
+			v->value = ++i->max_obj;
+	}
+
+	if (!i->head)
+		i->head = v;
+	if (i->tail)
+		i->tail->next = v;
+	i->tail = v;
+}
+
+
+struct idval *
+id_find(struct idinfo *oi, const char *val, int type, int id)
+{
+	struct idval *v;
+
+	if (!val && !id)
+		return NULL;
+
+	/* linear search */
+	for (v = oi->head; v; v = v->next) {
+		if (v->type != type)
+			continue;
+		if (val && !strcmp(val, v->name))
+			return v;
+		if (id && id == v->value)
+			return v;
+	}
+
+	return NULL;
+}
+
+
+void
+id_dump(struct idinfo *oi, FILE *fp)
+{
+	struct idval *v;
+
+	fprintf(fp, "# Max attribute value: %d\n", oi->max_attr);
+	fprintf(fp, "# Max object class value: %d\n", oi->max_obj);
+
+	for (v = oi->head; v; v = v->next) {
+		fprintf(fp, "%s,%s,%s,%d\n", v->type==OBJ?"obj":"attr",
+			v->name, v->rawname, v->value);
+	}
+}
+
+
+
+int
+id_writefile(struct idinfo *oi, char *filename)
+{
+	char tmpfn[4096];
+	FILE *fp;
+	int fd;
+
+	snprintf(tmpfn, sizeof(tmpfn), "%s.XXXXXX", filename);
+	fd = mkstemp(tmpfn);
+	if (fd < 0)
+		return -1;
+
+	fp = fdopen(fd, "w");
+	if (!fp) {
+		close(fd);
+		unlink(tmpfn);
+		return -1;
+	}
+
+	id_dump(oi, fp);
+	fflush(fp);
+	fsync(fd);
+	fclose(fp);
+	close(fd);
+
+	/* done */
+	rename(tmpfn, filename);
+
+	return 0;
+}
+
+
+int
+id_readfile(struct idinfo *oi, char *filename)
+{
+	char *c, *valp;
+	struct idval *v;
+	struct idval *tmp;
+	FILE *fp;
+	char buf[4096];
+	int len, lineno = 0, entries = 0;
+
+	fp = fopen(filename, "r");
+	if (!filename) {
+		perror("fopen");
+		return 1;
+	}
+
+	while (fgets(buf, sizeof(buf), fp)) {
+		++lineno;
+		if (!strlen(buf))
+			continue;
+		if (buf[0] == '#')
+			continue;
+		len = strlen(buf);
+		while (buf[len-1] < ' ') {
+			buf[len-1] = 0;
+			--len;
+		}
+		v = zalloc(sizeof(*v));
+
+		/* Attribute / object */
+		c = strchr(buf, ',');
+		if (!c || strlen(c) == 1) {
+			fprintf(stderr,
+				"%s: Malformed input on line %d: '%s'\n",
+				filename, lineno, buf);
+			exit(-2);
+		}
+
+		*c = 0;
+		c++;
+		if (!strncasecmp(buf, "attr",4)) {
+			v->type = ATTR;
+		} else if (!strncasecmp(buf, "obj", 3)) {
+			v->type = OBJ;
+		} else {
+			fprintf(stderr, "%s: Unknown type on line %d: '%s'\n",
+				filename, lineno, buf);
+			exit(-2);
+		}
+
+		valp = strchr(c, ',');
+		if (valp) {
+			*valp = 0;
+			valp++;
+		}
+		v->name = strdup(c);
+		assert(v->name);
+
+		c = valp;
+
+		valp = strchr(c, ',');
+		v->value = 0;
+		if (valp) {
+			*valp = 0;
+			valp++;
+			if (strlen(valp))
+				v->value = atoi(valp);
+		}
+
+		v->rawname = strdup(c);
+		assert(v->rawname);
+
+		if (!id_find(oi, v->name, v->type, 0)) {
+			tmp = id_find(oi, NULL, v->type, v->value);
+			if (tmp) {
+				fprintf(stderr, "%s: Duplicate id value: "
+					"%d & %d, type %d\n", filename,
+					tmp->value, v->value, v->type);
+				exit(-1);
+			}
+			id_insert(oi, v);
+		}
+
+		++entries;
+	}
+
+	fclose(fp);
+
+	return 0;
+}
diff --git a/config/tools/ldap/rng2ldif/value-list.h b/config/tools/ldap/rng2ldif/value-list.h
new file mode 100644
index 0000000..4e83e08
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/value-list.h
@@ -0,0 +1,29 @@
+/** License: GPLv2 */
+#ifndef _VALUE_LIST_H
+#define _VALUE_LIST_H
+
+struct idval {
+	struct idval *next;
+	char *name;
+	char *rawname;
+	int type;
+	int value;
+};
+
+struct idinfo {
+	struct idval *head;
+	struct idval *tail;
+	int max_obj;
+	int max_attr;
+};
+
+void id_insert(struct idinfo *i, struct idval *v);
+struct idval * id_find(struct idinfo *oi, const char *val, int type, int id);
+void id_dump(struct idinfo *oi, FILE *fp);
+int id_readfile(struct idinfo *oi, char *filename);
+int id_writefile(struct idinfo *oi, char *filename);
+
+#define OBJ 1
+#define ATTR 0
+
+#endif
diff --git a/config/tools/ldap/rng2ldif/zalloc.c b/config/tools/ldap/rng2ldif/zalloc.c
new file mode 100644
index 0000000..f05306d
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/zalloc.c
@@ -0,0 +1,23 @@
+#include <malloc.h>
+#include <string.h>
+#include <assert.h>
+#include "zalloc.h"
+
+void *
+zalloc(size_t size)
+{
+	void *ret;
+	size_t oddball;
+
+	oddball = ( size % sizeof(void *) );
+	if (oddball) {
+		size -= oddball;
+		size += sizeof(void *);
+	}
+
+	ret = malloc(size);
+	if (!ret) 
+		assert(0);
+	memset(ret, 0, size);
+	return ret;
+}
diff --git a/config/tools/ldap/rng2ldif/zalloc.h b/config/tools/ldap/rng2ldif/zalloc.h
new file mode 100644
index 0000000..0992ec2
--- /dev/null
+++ b/config/tools/ldap/rng2ldif/zalloc.h
@@ -0,0 +1,6 @@
+#ifndef _ZALLOC_H
+#define _ZALLOC_H
+
+void *zalloc(size_t size);
+
+#endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]