[gq-commit] gq/src xmlparse.c,NONE,1.1 xmlparse.h,NONE,1.1 gq-xml.c,NONE,1.1 gq-xml.h,NONE,1.1
Status: Beta
Brought to you by:
sur5r
From: <sta...@us...> - 2003-10-04 06:57:13
|
Update of /cvsroot/gqclient/gq/src In directory sc8-pr-cvs1:/tmp/cvs-serv13663 Added Files: xmlparse.c xmlparse.h gq-xml.c gq-xml.h Log Message: * First check-in of a libxml based configuration file parser. The parser uses the SAX interface and can be easily extended. It can also be extended easily to other XML files * As noted: Requires libxml or libxml2 * The parser is driven by a data structure pointing to start and end element headers for the used tags. Those handlers can be context sensitive --- NEW FILE: xmlparse.c --- /* GQ -- a GTK-based LDAP client is Copyright (C) 1998-2003 Bert Vermeulen Copyright (C) 2002-2003 Peter Stamfest This file is Copyright (c) 2003 by Peter Stamfest <pe...@st...> This program is released under the Gnu General Public License with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <string.h> #include <gtk/gtk.h> #include "xmlparse.h" #define malloc g_malloc #define malloc0 g_malloc0 #define calloc(n,s) g_malloc0(n * s) #define TAGSTACK_INCR 20 #if 0 void free_tagstack_entry(struct tagstack_entry *e); struct tagstack *new_tagstack(); void free_tagstack(struct tagstack *stack); struct tagstack_entry *push_tag(struct tagstack *stack, const xmlChar *tag, const xmlChar **attrs); void pop_tag(struct tagstack *stack); /* retrieve the n-th tagstack entry. 0 = the top entry, 1 = the next-to-top entry, etc... */ #endif static void free_tagstack_entry(struct tagstack_entry *e) { int i; if (e->tag) free(e->tag); e->tag = NULL; if (e->cdata) free(e->cdata); e->cdata = NULL; if (e->free_data) e->free_data(e->data); e->data = NULL; e->free_data = NULL; if (e->attrs) { for (i = 0 ; e->attrs[i] ; i++) { free(e->attrs[i]); e->attrs[i] = NULL; } free(e->attrs); e->attrs = NULL; } } static struct tagstack *new_tagstack() { struct tagstack *s = calloc(1, sizeof (struct tagstack)); s->size = TAGSTACK_INCR; s->entries = calloc(s->size, sizeof(struct tagstack_entry *)); return s; } static struct tagstack_entry *push_tag(struct tagstack *stack, const xmlChar *tag, const xmlChar **attrs) { struct tagstack_entry *e = calloc(1, sizeof (struct tagstack_entry)); if (stack->sp >= stack->size) { stack->size += TAGSTACK_INCR; stack->entries = realloc(stack->entries, sizeof(struct tagstack_entry *) * stack->size); } stack->entries[stack->sp++] = e; e->tag = strdup(tag); return e; } static void pop_tag(struct tagstack *stack) { if (stack->sp-- > 0) { struct tagstack_entry *e = stack->entries[stack->sp]; stack->entries[stack->sp] = NULL; free_tagstack_entry(e); } } static void free_tagstack(struct tagstack *stack) { while (stack->sp-- > 0) pop_tag(stack); } /* retrieve the n-th tagstack entry. 0 = the top entry, 1 = the next-to-top entry, etc... */ struct tagstack_entry *peek_tag(struct tagstack *stack, int n) { int i = stack->sp - 1 - n; if (i >= 0) { return stack->entries[i]; } else { return NULL; } } static void startElementH(struct parser_context *ctx, const xmlChar *name, const xmlChar **attrs) { struct tagstack_entry *e; const struct xml_tag *t; int i; #ifdef SKIP_UNKNOWN int parent_skip; e = peek_tag(ctx->stack, 0); parent_skip = e && e->skip; #endif e = push_tag(ctx->stack, name, attrs); #ifdef SKIP_UNKNOWN if (parent_skip) { /* we are currently skipping tags recursively */ e->skip = 1; return; } #endif e->attrs = NULL; if (attrs) { for (i = 0 ; attrs[i] ; i++) ; e->attrs = calloc(i, sizeof(xmlChar *)); for (i = 0 ; attrs[i] ; i++) { e->attrs[i] = strdup(attrs[i]); } } /* lookup handler */ for (t = ctx->tags ; t->tag ; t++) { if (strcmp(name, t->tag) == 0) { /* maybe, maybe, maybe..... (J Joplin) */ int i; int ok = 1; /* check context */ for (i = 0 ; i < XML_CONTEXT_SIZE && t->context[i] ; i++) { struct tagstack_entry *f; f = peek_tag(ctx->stack, i + 1); if (!f) { ok = 0; break; } if (strcmp(f->tag, t->context[i]) != 0) { ok = 0; break; } } if (ok) { /* found handler !!! */ break; } } } if (t->tag) { e->handler = t; if (e->handler->startElement) { e->handler->startElement(ctx, e); } } else { #ifdef SKIP_UNKNOWN e->skip = 1; #else XMLhandleFatalError(ctx, "Unknown tag '%s'\n", name); #endif } } static void endElementH(struct parser_context *ctx, const xmlChar *name) { struct tagstack_entry *e = peek_tag(ctx->stack, 0); if (e->cdata && e->handler && !(e->handler->flags & NO_TRIM_CDATA)) { gunichar c; xmlChar *p = e->cdata, *n = NULL; for(c = g_utf8_get_char(p) ; c ; c = g_utf8_next_char(p)) { if (!g_unichar_isspace(c)) { memmove(e->cdata, p, e->len - (p - e->cdata) + 1); break; } } p = e->cdata; for(c = g_utf8_get_char(p) ; c ; c = g_utf8_next_char(p)) { if (g_unichar_isspace(c)) { if (n == NULL) n = p; } else { n = NULL; } } if (n) { *n = 0; } } if (!e->skip && e->handler) { if (e->handler->endElement) { e->handler->endElement(ctx, e); } } pop_tag(ctx->stack); } static void charactersH(struct parser_context *ctx, const xmlChar *ch, int len) { struct tagstack_entry *e = peek_tag(ctx->stack, 0); if (e->skip) return; if (e->cdata) { e->len += len; e->cdata = realloc(e->cdata, e->len + 1); } else { e->len += len; e->cdata = malloc(e->len + 1); *(e->cdata) = 0; } strncat(e->cdata, ch, len); e->cdata[len] = 0; } int XMLparse(struct xml_tag *tags, xmlSAXHandler *handler, void *user_data, const char *file) { struct parser_context ctx; struct tagstack *stack = new_tagstack(); int rc; int handler_is_local = 0; if (handler == NULL) { handler = calloc(1, sizeof(xmlSAXHandler)); handler_is_local = 1; } if (!handler->startElement) { handler->startElement = (startElementSAXFunc) startElementH; } if (!handler->endElement) { handler->endElement = (endElementSAXFunc) endElementH; } if (!handler->characters) { handler->characters = (charactersSAXFunc) charactersH; } ctx.tags = tags; ctx.stack = stack; ctx.user_data = user_data; ctx.XMLhandler = handler; rc = xmlSAXUserParseFile(handler, &ctx, file); free_tagstack(stack); if (handler_is_local) free(handler); return rc; } --- NEW FILE: xmlparse.h --- /* GQ -- a GTK-based LDAP client Copyright (C) 1998-2003 Bert Vermeulen Copyright (C) 2002-2003 by Peter Stamfest This program is released under the Gnu General Public License with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: xmlparse.h,v 1.1 2003/10/04 06:57:03 stamfest Exp $ */ #ifndef GQ_XMLPARSE_H_INCLUDED #define GQ_XMLPARSE_H_INCLUDED #include "config.h" #ifdef HAVE_LIBXML2 # include <libxml/SAX.h> #elif defined(HAVE_LIBXML) # include <gnome-xml/SAX.h> #elif defined(HAVE_EXPAT) # include <expat.h> typedef xmlChar XML_Char; #endif #include "utf8-compat.h" #define XML_CONTEXT_SIZE 10 #define NO_TRIM_CDATA 1 struct xml_tag; typedef void (*free_func)(void *); struct tagstack_entry { xmlChar *tag; xmlChar **attrs; xmlChar *cdata; int len; const struct xml_tag *handler; /* if skip is set to 1, all tags below will be skipped (no xml_tag handlers will be called) */ int skip; void *data; free_func free_data; /* void (*free_data)(void *); */ }; struct tagstack { int size; int sp; struct tagstack_entry **entries; }; struct parser_context; struct xml_tag { const char *tag; int flags; void (*startElement)(struct parser_context *ctx, struct tagstack_entry *stack); void (*endElement) (struct parser_context *ctx, struct tagstack_entry *stack); const char *context[XML_CONTEXT_SIZE]; }; struct parser_context { struct tagstack *stack; const struct xml_tag *tags; void *user_data; xmlSAXHandler *XMLhandler; }; #define XMLhandleFatalError(ctx, ...) \ if (ctx->XMLhandler->fatalError) { \ ctx->XMLhandler->fatalError(ctx, __VA_ARGS__); \ } else { \ fprintf(stderr, "Unhandled fatal error: "); fprintf(stderr, __VA_ARGS__); \ exit(1); \ } #define XMLhandleError(ctx, ...) \ if (ctx->XMLhandler->error) { \ ctx->XMLhandler->error(ctx, __VA_ARGS__); \ } else { \ fprintf(stderr, "Unhandled error: "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); \ exit(1); \ } struct tagstack_entry *peek_tag(struct tagstack *stack, int n); int XMLparse(struct xml_tag *tags, xmlSAXHandler *handler, void *user_data, const char *file); #endif /* Local Variables: c-basic-offset: 4 End: */ --- NEW FILE: gq-xml.c --- /* GQ -- a GTK-based LDAP client is Copyright (C) 1998-2003 Bert Vermeulen Copyright (C) 2002-2003 Peter Stamfest This file is Copyright (c) 2003 by Peter Stamfest <pe...@st...> This program is released under the Gnu General Public License with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <string.h> #include <gtk/gtk.h> #include "gq-xml.h" #include "xmlparse.h" #include "configfile.h" #include "util.h" #include "i18n.h" #include "ldif.h" #include "syntax.h" #include "filter.h" #include "template.h" #include "errorchain.h" struct cf_comm { int error_context; int severity; struct gq_config *config; }; static void gq_configS(struct parser_context *ctx, struct tagstack_entry *e) { e->data = calloc(1, sizeof(struct gq_config)); default_config(e->data); } static void gq_configE(struct parser_context *ctx, struct tagstack_entry *e) { if (ctx->user_data) { struct cf_comm *comm = (struct cf_comm *)ctx->user_data; if (comm->config) { free_config(comm->config); } comm->config = e->data; e->data = NULL; } } long longCDATA(struct parser_context *ctx, struct tagstack_entry *e) { char *ep; long l; l = strtol(e->cdata, &ep, 10); if ((ep && *ep) || l < 0) { XMLhandleError(ctx, _("Non-negative integer CDATA expected ('%s')"), e->tag); return -1; } return l; } static int booleanCDATA(struct parser_context *ctx, struct tagstack_entry *e) { int b; if (strcasecmp("true", e->cdata) == 0) { b = 1; } else if (strcasecmp("false", e->cdata) == 0) { b = 0; } else { XMLhandleError(ctx, _("Boolean CDATA ('true' or 'false') expected ('%s')"), e->tag); return -1; } return b; } static void config_versionE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) c->config_version = l; } static void asked_config_versionE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) c->asked_version = l; } static void last_askedE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) c->last_asked = l; } static void confirm_modE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) c->confirm_mod = b; } static void show_dnE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) c->showdn = b; } static void show_ocE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) c->showoc = b; } static void show_rdn_onlyE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) c->show_rdn_only = b; } static void sort_search_modeE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) c->sort_search = b; } static void sort_browse_modeE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) c->sort_browse = b; } static void ldif_formatE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; int t = tokenize(token_ldifformat, e->cdata); c->ldifformat = t; } static void search_argumentE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; /* compatibility with older versions of gq -- accept token number as well */ gunichar ch = g_utf8_get_char(e->cdata); if (g_unichar_isdigit(ch)) { long l = longCDATA(ctx, e); if (l >= 0) { c->search_argument = l; } else { XMLhandleError(ctx, _("Invalid token for '%s'"), e->tag); } } else { int t = tokenize(token_searchargument, e->cdata); c->search_argument = t; } } static void schema_serverE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF-8 safe */ strncpy(c->schemaserver, e->cdata, MAX_SERVERNAME_LEN - 1); } static void ldapserverS(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = calloc(1, sizeof(struct ldapserver)); init_ldapserver(server); e->data = server; } static void ldapserverE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; struct ldapserver *server = e->data; if (strcasecmp(server->pwencoding, "Base64") == 0 && server->bindpw[0]) { GByteArray *o = g_byte_array_new(); b64_decode(o, server->bindpw, strlen(server->bindpw)); memset(server->bindpw, 0, sizeof(server->bindpw)); strncpy(server->bindpw, o->data, MIN(o->len, sizeof(server->bindpw) - 1)); } else if (server->bindpw[0] && server->pwencoding[0]) { XMLhandleError(ctx, _("Unsupported password encoding")); } if(c->ldapservers) { server = c->ldapservers; while(server->next) server = server->next; server->next = e->data; } else { c->ldapservers = e->data; } e->data = NULL; } static void ldapserver_nameE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->name, e->cdata, sizeof(server->name) - 1); } static void ldapserver_ldaphostE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->ldaphost, e->cdata, sizeof(server->ldaphost) - 1); } static void ldapserver_ldapportE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) server->ldapport = l; } static void ldapserver_basednE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->basedn, e->cdata, sizeof(server->basedn) - 1); } static void ldapserver_binddnE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->binddn, e->cdata, sizeof(server->binddn) - 1); } static void ldapserver_bindpwE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->bindpw, e->cdata, sizeof(server->bindpw) - 1); } static void ldapserver_pw_encodingE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->pwencoding, e->cdata, sizeof(server->pwencoding) - 1); } static void ldapserver_bindtypeE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; int t = tokenize(token_bindtype, e->cdata); server->bindtype = t; } static void ldapserver_search_attributeE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(server->searchattr, e->cdata, sizeof(server->searchattr) - 1); } static void ldapserver_ask_pwE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) server->ask_pw = b; } static void ldapserver_hide_internalE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) server->hide_internal = b; } static void ldapserver_show_refE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) server->show_ref = b; } static void ldapserver_enable_tlsE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) server->enabletls = b; } static void ldapserver_cache_connectionE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; int b = booleanCDATA(ctx, e); if (b >= 0) server->cacheconn = b; } static void ldapserver_local_cache_timeoutE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) server->local_cache_timeout = l; } static void ldapserver_maxentriesE(struct parser_context *ctx, struct tagstack_entry *e) { struct ldapserver *server = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) server->maxentries = l; } static void filterS(struct parser_context *ctx, struct tagstack_entry *e) { e->data = calloc(1, sizeof(struct gq_filter)); e->free_data = free; } static void filterE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; c->filters = g_list_append(c->filters, e->data); e->data = NULL; e->free_data = NULL; } static void filter_nameE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(filter->name, e->cdata, sizeof(filter->name) - 1); } static void filter_ldapfilterE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(filter->ldapfilter, e->cdata, sizeof(filter->ldapfilter) - 1); } static void filter_servernameE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(filter->servername, e->cdata, sizeof(filter->servername) - 1); } static void filter_basednE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_filter *filter = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(filter->basedn, e->cdata, sizeof(filter->basedn) - 1); } static void templateS(struct parser_context *ctx, struct tagstack_entry *e) { e->data = calloc(1, sizeof(struct gq_template)); } static void templateE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 1)->data; c->templates = g_list_append(c->templates, e->data); } static void template_nameE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_template *t = peek_tag(ctx->stack, 1)->data; /* FIXME - not UTF8-safe */ strncpy(t->name, e->cdata, sizeof(t->name) - 1); } static void template_objectclassE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_template *t = peek_tag(ctx->stack, 1)->data; t->objectclasses = g_list_append(t->objectclasses, strdup(e->cdata)); } struct ddt { char *attr; long dt; }; static void free_ddt(struct ddt *d) { if (d) { if (d->attr) free(d->attr); d->attr = NULL; free(d); } } static void display_typeS(struct parser_context *ctx, struct tagstack_entry *e) { e->data = calloc(1, sizeof(struct ddt)); e->free_data = (free_func) free_ddt; } static void display_typeE(struct parser_context *ctx, struct tagstack_entry *e) { struct gq_config *c = peek_tag(ctx->stack, 3)->data; struct ddt *d = e->data; if (d->attr) { if (get_dt_handler(d->dt)) { int *p = (int *) g_malloc(sizeof(int)); *p = d->dt; g_hash_table_insert(c->defaultDT, d->attr, p); d->attr = NULL; /* stored in hash table */ } } } static void ldapserver_dt_attributeE(struct parser_context *ctx, struct tagstack_entry *e) { struct ddt *d = peek_tag(ctx->stack, 1)->data; if (d->attr) free(d->attr); d->attr = strdup(e->cdata); } static void ldapserver_dt_defaultE(struct parser_context *ctx, struct tagstack_entry *e) { struct ddt *d = peek_tag(ctx->stack, 1)->data; long l = longCDATA(ctx, e); if (l >= 0) d->dt = l; } struct xml_tag config_tags[] = { { "gq-config", 0, gq_configS, gq_configE, { NULL }, }, { "config-version", 0, NULL, config_versionE, { "gq-config", NULL }, }, { "asked-config-version", 0, NULL, asked_config_versionE, { "gq-config", NULL }, }, { "last-asked", 0, NULL, last_askedE, { "gq-config", NULL }, }, { "confirm-mod", 0, NULL, confirm_modE, { "gq-config", NULL }, }, { "search-argument", 0, NULL, search_argumentE, { "gq-config", NULL }, }, { "show-dn", 0, NULL, show_dnE, { "gq-config", NULL }, }, { "show-oc", 0, NULL, show_ocE, { "gq-config", NULL }, }, { "show-rdn-only", 0, NULL, show_rdn_onlyE, { "gq-config", NULL }, }, { "sort-search-mode", 0, NULL, sort_search_modeE, { "gq-config", NULL }, }, { "sort-browse-mode", 0, NULL, sort_browse_modeE, { "gq-config", NULL }, }, { "ldif-format", 0, NULL, ldif_formatE, { "gq-config", NULL }, }, { "schema-server", 0, NULL, schema_serverE, { "gq-config", NULL }, }, /* ldapserver tags */ { "ldapserver", 0, ldapserverS, ldapserverE, { "gq-config", NULL }, }, { "name", 0, NULL, ldapserver_nameE, { "ldapserver", NULL }, }, { "ldaphost", 0, NULL, ldapserver_ldaphostE, { "ldapserver", NULL }, }, { "ldapport", 0, NULL, ldapserver_ldapportE, { "ldapserver", NULL }, }, { "basedn", 0, NULL, ldapserver_basednE, { "ldapserver", NULL }, }, { "binddn", 0, NULL, ldapserver_binddnE, { "ldapserver", NULL }, }, { "bindpw", 0, NULL, ldapserver_bindpwE, { "ldapserver", NULL }, }, { "pw-encoding", 0, NULL, ldapserver_pw_encodingE, { "ldapserver", NULL }, }, { "bindtype", 0, NULL, ldapserver_bindtypeE, { "ldapserver", NULL }, }, { "search-attribute", 0, NULL, ldapserver_search_attributeE, { "ldapserver", NULL }, }, { "ask-pw", 0, NULL, ldapserver_ask_pwE, { "ldapserver", NULL }, }, { "hide-internal", 0, NULL, ldapserver_hide_internalE, { "ldapserver", NULL }, }, { "show-ref", 0, NULL, ldapserver_show_refE, { "ldapserver", NULL }, }, { "enable-tls", 0, NULL, ldapserver_enable_tlsE, { "ldapserver", NULL }, }, { "cache-connection", 0, NULL, ldapserver_cache_connectionE, { "ldapserver", NULL }, }, { "local-cache-timeout", 0, NULL, ldapserver_local_cache_timeoutE, { "ldapserver", NULL }, }, { "maxentries", 0, NULL, ldapserver_maxentriesE, { "ldapserver", NULL }, }, /* templates */ { "template", 0, templateS, templateE, { "gq-config", NULL }, }, { "name", 0, NULL, template_nameE, { "template", NULL }, }, { "objectclass", 0, NULL, template_objectclassE, { "template", NULL }, }, /* filter */ { "filter", 0, filterS, filterE, { "gq-config", NULL }, }, { "name", 0, NULL, filter_nameE, { "filter", NULL }, }, { "ldapfilter", 0, NULL, filter_ldapfilterE, { "filter", NULL }, }, { "servername", 0, NULL, filter_servernameE, { "filter", NULL }, }, { "basedn", 0, NULL, filter_basednE, { "filter", NULL }, }, /* defaults */ { "defaults", 0, NULL, NULL, { "gq-config", NULL }, }, /* display-types */ { "display-types", 0, NULL, NULL, { "defaults", NULL }, }, /* display-type */ { "display-type", 0, display_typeS, display_typeE, { "display-types", "defaults", "gq-config", NULL }, }, { "dt-attribute", 0, NULL, ldapserver_dt_attributeE, { "display-type", NULL }, }, { "dt-default", 0, NULL, ldapserver_dt_defaultE, { "display-type", NULL }, }, { NULL }, }; static void XMLmessageHandler(struct parser_context *ctx, int severity, const char *type, const char *format, va_list ap) { struct cf_comm *comm = ctx->user_data; if (comm) { int len = 1024, pos = 0, i; char *buf = g_malloc(len); snprintf(buf, len, "%s: ", type); i = strlen(buf); pos += i; /* OK for UTF-8 */ vsnprintf(buf + pos, len - pos, format, ap); error_push(comm->error_context, buf); fprintf(stderr, "%s\n", buf); g_free(buf); comm->severity = severity; } } static void XMLwarningHandler(struct parser_context *ctx, const char *fmt, ...) { va_list args; va_start(args, fmt); XMLmessageHandler(ctx, 1, _("Warning"), fmt, args); va_end(args); } static void XMLerrorHandler(struct parser_context *ctx, const char *fmt, ...) { va_list args; va_start(args, fmt); XMLmessageHandler(ctx, 2, _("Error"), fmt, args); va_end(args); } static void XMLfatalErrorHandler(struct parser_context *ctx, const char *fmt, ...) { va_list args; va_start(args, fmt); XMLmessageHandler(ctx, 3, _("Fatal Error"), fmt, args); va_end(args); } struct gq_config *process_rcfile_XML(int error_context, const char *filename) { xmlSAXHandler *handler = g_malloc0(sizeof(xmlSAXHandler)); int rc; struct cf_comm comm; comm.error_context = error_context; comm.config = NULL; handler->error = (errorSAXFunc) XMLerrorHandler; handler->fatalError = (fatalErrorSAXFunc) XMLfatalErrorHandler; handler->warning = (warningSAXFunc) XMLwarningHandler; rc = XMLparse(config_tags, handler, &comm, filename); g_free(handler); if (rc != 0) { free_config(comm.config); comm.config = NULL; } printf("filen = %s config1 = %08lx\n", filename, comm.config); return comm.config; } int main_test(int argc, char **argv) { struct gq_config *config = NULL; int rc = 0; int load_context, write_context; init_syntaxes(); load_context = error_new_context(_("Error loading configfile")); /* rc = XMLparse(config_tags, NULL, &config, argv[1]); */ config = process_rcfile_XML(load_context, argv[1]); if (config) { write_context = error_new_context(_("Error writing configfile")); save_config_internal(write_context, config, "tmp-conf"); } return rc; } --- NEW FILE: gq-xml.h --- /* GQ -- a GTK-based LDAP client Copyright (C) 1998-2003 Bert Vermeulen Copyright (C) 2002-2003 by Peter Stamfest This program is released under the Gnu General Public License with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: gq-xml.h,v 1.1 2003/10/04 06:57:03 stamfest Exp $ */ #ifndef GQ_GQ_XML_H_INCLUDED #define GQ_GQ_XML_H_INCLUDED #include "config.h" #include "configfile.h" struct gq_config *process_rcfile_XML(int error_context, const char *filename); #endif |