17bd4e7b4SPoul-Henning Kamp /*-
2eb8f8877SWarner Losh * SPDX-License-Identifier: BSD-3-Clause
35e53a4f9SPedro F. Giffuni *
47bd4e7b4SPoul-Henning Kamp * Copyright (c) 2003 Poul-Henning Kamp
57bd4e7b4SPoul-Henning Kamp * All rights reserved.
67bd4e7b4SPoul-Henning Kamp *
77bd4e7b4SPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without
87bd4e7b4SPoul-Henning Kamp * modification, are permitted provided that the following conditions
97bd4e7b4SPoul-Henning Kamp * are met:
107bd4e7b4SPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright
117bd4e7b4SPoul-Henning Kamp * notice, this list of conditions and the following disclaimer.
127bd4e7b4SPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright
137bd4e7b4SPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the
147bd4e7b4SPoul-Henning Kamp * documentation and/or other materials provided with the distribution.
157bd4e7b4SPoul-Henning Kamp * 3. The names of the authors may not be used to endorse or promote
167bd4e7b4SPoul-Henning Kamp * products derived from this software without specific prior written
177bd4e7b4SPoul-Henning Kamp * permission.
187bd4e7b4SPoul-Henning Kamp *
197bd4e7b4SPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
207bd4e7b4SPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
217bd4e7b4SPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
227bd4e7b4SPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
237bd4e7b4SPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
247bd4e7b4SPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
257bd4e7b4SPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
267bd4e7b4SPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
277bd4e7b4SPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
287bd4e7b4SPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
297bd4e7b4SPoul-Henning Kamp * SUCH DAMAGE.
307bd4e7b4SPoul-Henning Kamp */
317bd4e7b4SPoul-Henning Kamp
327bd4e7b4SPoul-Henning Kamp #include <stdio.h>
337bd4e7b4SPoul-Henning Kamp #include <inttypes.h>
347bd4e7b4SPoul-Henning Kamp #include <stdlib.h>
357bd4e7b4SPoul-Henning Kamp #include <string.h>
367bd4e7b4SPoul-Henning Kamp #include <unistd.h>
377bd4e7b4SPoul-Henning Kamp #include <errno.h>
38bd0f3d34SAlexander Motin #include <paths.h>
397bd4e7b4SPoul-Henning Kamp #include <fcntl.h>
407bd4e7b4SPoul-Henning Kamp #include <ctype.h>
417bd4e7b4SPoul-Henning Kamp #include <sys/stat.h>
427bd4e7b4SPoul-Henning Kamp #include <sys/mman.h>
437bd4e7b4SPoul-Henning Kamp #include <sys/queue.h>
447bd4e7b4SPoul-Henning Kamp #include <sys/sbuf.h>
457bd4e7b4SPoul-Henning Kamp #include <sys/sysctl.h>
467bd4e7b4SPoul-Henning Kamp #include <err.h>
477bd4e7b4SPoul-Henning Kamp #include <bsdxml.h>
487bd4e7b4SPoul-Henning Kamp #include <libgeom.h>
497bd4e7b4SPoul-Henning Kamp
507bd4e7b4SPoul-Henning Kamp struct mystate {
517bd4e7b4SPoul-Henning Kamp struct gmesh *mesh;
527bd4e7b4SPoul-Henning Kamp struct gclass *class;
537bd4e7b4SPoul-Henning Kamp struct ggeom *geom;
547bd4e7b4SPoul-Henning Kamp struct gprovider *provider;
557bd4e7b4SPoul-Henning Kamp struct gconsumer *consumer;
567bd4e7b4SPoul-Henning Kamp int level;
577bd4e7b4SPoul-Henning Kamp struct sbuf *sbuf[20];
587bd4e7b4SPoul-Henning Kamp struct gconf *config;
59019100deSJuli Mallett int nident;
60e8f6ee4aSJaakko Heinonen XML_Parser parser;
61e8f6ee4aSJaakko Heinonen int error;
627bd4e7b4SPoul-Henning Kamp };
637bd4e7b4SPoul-Henning Kamp
647bd4e7b4SPoul-Henning Kamp static void
StartElement(void * userData,const char * name,const char ** attr)657bd4e7b4SPoul-Henning Kamp StartElement(void *userData, const char *name, const char **attr)
667bd4e7b4SPoul-Henning Kamp {
677bd4e7b4SPoul-Henning Kamp struct mystate *mt;
687bd4e7b4SPoul-Henning Kamp void *id;
697bd4e7b4SPoul-Henning Kamp void *ref;
707bd4e7b4SPoul-Henning Kamp int i;
717bd4e7b4SPoul-Henning Kamp
727bd4e7b4SPoul-Henning Kamp mt = userData;
737bd4e7b4SPoul-Henning Kamp mt->level++;
742616144eSDag-Erling Smørgrav mt->sbuf[mt->level] = sbuf_new_auto();
757bd4e7b4SPoul-Henning Kamp id = NULL;
76ccac9da4SJohn Baldwin ref = NULL;
777bd4e7b4SPoul-Henning Kamp for (i = 0; attr[i] != NULL; i += 2) {
787bd4e7b4SPoul-Henning Kamp if (!strcmp(attr[i], "id")) {
79c70d61d5SHiroki Sato id = (void *)strtoul(attr[i + 1], NULL, 0);
80019100deSJuli Mallett mt->nident++;
817bd4e7b4SPoul-Henning Kamp } else if (!strcmp(attr[i], "ref")) {
82c70d61d5SHiroki Sato ref = (void *)strtoul(attr[i + 1], NULL, 0);
837bd4e7b4SPoul-Henning Kamp } else
847bd4e7b4SPoul-Henning Kamp printf("%*.*s[%s = %s]\n",
857bd4e7b4SPoul-Henning Kamp mt->level + 1, mt->level + 1, "",
867bd4e7b4SPoul-Henning Kamp attr[i], attr[i + 1]);
877bd4e7b4SPoul-Henning Kamp }
887bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "class") && mt->class == NULL) {
897bd4e7b4SPoul-Henning Kamp mt->class = calloc(1, sizeof *mt->class);
907b6942a1SUlf Lilleengen if (mt->class == NULL) {
91e8f6ee4aSJaakko Heinonen mt->error = errno;
92e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
937b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
947b6942a1SUlf Lilleengen "element", name);
957b6942a1SUlf Lilleengen return;
967b6942a1SUlf Lilleengen }
97ccac9da4SJohn Baldwin mt->class->lg_id = id;
98ccac9da4SJohn Baldwin LIST_INSERT_HEAD(&mt->mesh->lg_class, mt->class, lg_class);
99ccac9da4SJohn Baldwin LIST_INIT(&mt->class->lg_geom);
100ccac9da4SJohn Baldwin LIST_INIT(&mt->class->lg_config);
1017bd4e7b4SPoul-Henning Kamp return;
1027bd4e7b4SPoul-Henning Kamp }
1037bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "geom") && mt->geom == NULL) {
1047bd4e7b4SPoul-Henning Kamp mt->geom = calloc(1, sizeof *mt->geom);
1057b6942a1SUlf Lilleengen if (mt->geom == NULL) {
106e8f6ee4aSJaakko Heinonen mt->error = errno;
107e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
1087b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
1097b6942a1SUlf Lilleengen "element", name);
1107b6942a1SUlf Lilleengen return;
1117b6942a1SUlf Lilleengen }
112ccac9da4SJohn Baldwin mt->geom->lg_id = id;
113ccac9da4SJohn Baldwin LIST_INSERT_HEAD(&mt->class->lg_geom, mt->geom, lg_geom);
114ccac9da4SJohn Baldwin LIST_INIT(&mt->geom->lg_provider);
115ccac9da4SJohn Baldwin LIST_INIT(&mt->geom->lg_consumer);
116ccac9da4SJohn Baldwin LIST_INIT(&mt->geom->lg_config);
1177bd4e7b4SPoul-Henning Kamp return;
1187bd4e7b4SPoul-Henning Kamp }
1197bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "class") && mt->geom != NULL) {
120ccac9da4SJohn Baldwin mt->geom->lg_class = ref;
1217bd4e7b4SPoul-Henning Kamp return;
1227bd4e7b4SPoul-Henning Kamp }
1237bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "consumer") && mt->consumer == NULL) {
1247bd4e7b4SPoul-Henning Kamp mt->consumer = calloc(1, sizeof *mt->consumer);
1257b6942a1SUlf Lilleengen if (mt->consumer == NULL) {
126e8f6ee4aSJaakko Heinonen mt->error = errno;
127e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
1287b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
1297b6942a1SUlf Lilleengen "element", name);
1307b6942a1SUlf Lilleengen return;
1317b6942a1SUlf Lilleengen }
132ccac9da4SJohn Baldwin mt->consumer->lg_id = id;
133ccac9da4SJohn Baldwin LIST_INSERT_HEAD(&mt->geom->lg_consumer, mt->consumer,
134ccac9da4SJohn Baldwin lg_consumer);
135ccac9da4SJohn Baldwin LIST_INIT(&mt->consumer->lg_config);
1367bd4e7b4SPoul-Henning Kamp return;
1377bd4e7b4SPoul-Henning Kamp }
1387bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "geom") && mt->consumer != NULL) {
139ccac9da4SJohn Baldwin mt->consumer->lg_geom = ref;
1407bd4e7b4SPoul-Henning Kamp return;
1417bd4e7b4SPoul-Henning Kamp }
1427bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "provider") && mt->consumer != NULL) {
143ccac9da4SJohn Baldwin mt->consumer->lg_provider = ref;
1447bd4e7b4SPoul-Henning Kamp return;
1457bd4e7b4SPoul-Henning Kamp }
1467bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "provider") && mt->provider == NULL) {
1477bd4e7b4SPoul-Henning Kamp mt->provider = calloc(1, sizeof *mt->provider);
1487b6942a1SUlf Lilleengen if (mt->provider == NULL) {
149e8f6ee4aSJaakko Heinonen mt->error = errno;
150e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
1517b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
1527b6942a1SUlf Lilleengen "element", name);
1537b6942a1SUlf Lilleengen return;
1547b6942a1SUlf Lilleengen }
155ccac9da4SJohn Baldwin mt->provider->lg_id = id;
156ccac9da4SJohn Baldwin LIST_INSERT_HEAD(&mt->geom->lg_provider, mt->provider,
157ccac9da4SJohn Baldwin lg_provider);
158ccac9da4SJohn Baldwin LIST_INIT(&mt->provider->lg_consumers);
159ccac9da4SJohn Baldwin LIST_INIT(&mt->provider->lg_config);
1607bd4e7b4SPoul-Henning Kamp return;
1617bd4e7b4SPoul-Henning Kamp }
1627bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "geom") && mt->provider != NULL) {
163ccac9da4SJohn Baldwin mt->provider->lg_geom = ref;
1647bd4e7b4SPoul-Henning Kamp return;
1657bd4e7b4SPoul-Henning Kamp }
1667bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "config")) {
1677bd4e7b4SPoul-Henning Kamp if (mt->provider != NULL) {
168ccac9da4SJohn Baldwin mt->config = &mt->provider->lg_config;
1697bd4e7b4SPoul-Henning Kamp return;
1707bd4e7b4SPoul-Henning Kamp }
1717bd4e7b4SPoul-Henning Kamp if (mt->consumer != NULL) {
172ccac9da4SJohn Baldwin mt->config = &mt->consumer->lg_config;
1737bd4e7b4SPoul-Henning Kamp return;
1747bd4e7b4SPoul-Henning Kamp }
1757bd4e7b4SPoul-Henning Kamp if (mt->geom != NULL) {
176ccac9da4SJohn Baldwin mt->config = &mt->geom->lg_config;
1777bd4e7b4SPoul-Henning Kamp return;
1787bd4e7b4SPoul-Henning Kamp }
1797bd4e7b4SPoul-Henning Kamp if (mt->class != NULL) {
180ccac9da4SJohn Baldwin mt->config = &mt->class->lg_config;
1817bd4e7b4SPoul-Henning Kamp return;
1827bd4e7b4SPoul-Henning Kamp }
1837bd4e7b4SPoul-Henning Kamp }
1847bd4e7b4SPoul-Henning Kamp }
1857bd4e7b4SPoul-Henning Kamp
1867bd4e7b4SPoul-Henning Kamp static void
EndElement(void * userData,const char * name)1877bd4e7b4SPoul-Henning Kamp EndElement(void *userData, const char *name)
1887bd4e7b4SPoul-Henning Kamp {
1897bd4e7b4SPoul-Henning Kamp struct mystate *mt;
1905523c82cSAlexander Motin struct gconf *c;
1917bd4e7b4SPoul-Henning Kamp struct gconfig *gc;
1927bd4e7b4SPoul-Henning Kamp char *p;
1937bd4e7b4SPoul-Henning Kamp
1947bd4e7b4SPoul-Henning Kamp mt = userData;
195e8f6ee4aSJaakko Heinonen p = NULL;
196e8f6ee4aSJaakko Heinonen if (sbuf_finish(mt->sbuf[mt->level]) == 0)
1977bd4e7b4SPoul-Henning Kamp p = strdup(sbuf_data(mt->sbuf[mt->level]));
198e8f6ee4aSJaakko Heinonen sbuf_delete(mt->sbuf[mt->level]);
199e8f6ee4aSJaakko Heinonen mt->sbuf[mt->level] = NULL;
200e8f6ee4aSJaakko Heinonen mt->level--;
2017b6942a1SUlf Lilleengen if (p == NULL) {
202e8f6ee4aSJaakko Heinonen mt->error = errno;
203e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
2047b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
2057b6942a1SUlf Lilleengen "element", name);
2067b6942a1SUlf Lilleengen return;
2077b6942a1SUlf Lilleengen }
2087bd4e7b4SPoul-Henning Kamp if (strlen(p) == 0) {
2097bd4e7b4SPoul-Henning Kamp free(p);
2107bd4e7b4SPoul-Henning Kamp p = NULL;
2117bd4e7b4SPoul-Henning Kamp }
2127bd4e7b4SPoul-Henning Kamp
2137bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "name")) {
2147bd4e7b4SPoul-Henning Kamp if (mt->provider != NULL) {
215ccac9da4SJohn Baldwin mt->provider->lg_name = p;
2167bd4e7b4SPoul-Henning Kamp return;
2177bd4e7b4SPoul-Henning Kamp } else if (mt->geom != NULL) {
218ccac9da4SJohn Baldwin mt->geom->lg_name = p;
2197bd4e7b4SPoul-Henning Kamp return;
2207bd4e7b4SPoul-Henning Kamp } else if (mt->class != NULL) {
221ccac9da4SJohn Baldwin mt->class->lg_name = p;
2227bd4e7b4SPoul-Henning Kamp return;
2237bd4e7b4SPoul-Henning Kamp }
2247bd4e7b4SPoul-Henning Kamp }
2257bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "rank") && mt->geom != NULL) {
226ccac9da4SJohn Baldwin mt->geom->lg_rank = strtoul(p, NULL, 0);
2277bd4e7b4SPoul-Henning Kamp free(p);
2287bd4e7b4SPoul-Henning Kamp return;
2297bd4e7b4SPoul-Henning Kamp }
2307bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "mode") && mt->provider != NULL) {
231ccac9da4SJohn Baldwin mt->provider->lg_mode = p;
2327bd4e7b4SPoul-Henning Kamp return;
2337bd4e7b4SPoul-Henning Kamp }
2347bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "mode") && mt->consumer != NULL) {
235ccac9da4SJohn Baldwin mt->consumer->lg_mode = p;
2367bd4e7b4SPoul-Henning Kamp return;
2377bd4e7b4SPoul-Henning Kamp }
2387bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "mediasize") && mt->provider != NULL) {
239ccac9da4SJohn Baldwin mt->provider->lg_mediasize = strtoumax(p, NULL, 0);
2407bd4e7b4SPoul-Henning Kamp free(p);
2417bd4e7b4SPoul-Henning Kamp return;
2427bd4e7b4SPoul-Henning Kamp }
2437bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "sectorsize") && mt->provider != NULL) {
244ccac9da4SJohn Baldwin mt->provider->lg_sectorsize = strtoul(p, NULL, 0);
2457bd4e7b4SPoul-Henning Kamp free(p);
2467bd4e7b4SPoul-Henning Kamp return;
2477bd4e7b4SPoul-Henning Kamp }
24835daa28fSXin LI if (!strcmp(name, "stripesize") && mt->provider != NULL) {
24935daa28fSXin LI mt->provider->lg_stripesize = strtoumax(p, NULL, 0);
25035daa28fSXin LI free(p);
25135daa28fSXin LI return;
25235daa28fSXin LI }
25335daa28fSXin LI if (!strcmp(name, "stripeoffset") && mt->provider != NULL) {
25435daa28fSXin LI mt->provider->lg_stripeoffset = strtoumax(p, NULL, 0);
25535daa28fSXin LI free(p);
25635daa28fSXin LI return;
25735daa28fSXin LI }
2587bd4e7b4SPoul-Henning Kamp
2597bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "config")) {
2607bd4e7b4SPoul-Henning Kamp mt->config = NULL;
261e5437982SPedro F. Giffuni free(p);
2627bd4e7b4SPoul-Henning Kamp return;
2637bd4e7b4SPoul-Henning Kamp }
2647bd4e7b4SPoul-Henning Kamp
2655523c82cSAlexander Motin if (mt->config != NULL || (!strcmp(name, "wither") &&
2665523c82cSAlexander Motin (mt->provider != NULL || mt->geom != NULL))) {
2675523c82cSAlexander Motin if (mt->config != NULL)
2685523c82cSAlexander Motin c = mt->config;
2695523c82cSAlexander Motin else if (mt->provider != NULL)
2705523c82cSAlexander Motin c = &mt->provider->lg_config;
2715523c82cSAlexander Motin else
2725523c82cSAlexander Motin c = &mt->geom->lg_config;
2737b6942a1SUlf Lilleengen gc = calloc(1, sizeof *gc);
2747b6942a1SUlf Lilleengen if (gc == NULL) {
275e8f6ee4aSJaakko Heinonen mt->error = errno;
276e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
2777b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
2787b6942a1SUlf Lilleengen "element", name);
279ef9fc4afSXin LI free(p);
2807b6942a1SUlf Lilleengen return;
2817b6942a1SUlf Lilleengen }
282ccac9da4SJohn Baldwin gc->lg_name = strdup(name);
2837b6942a1SUlf Lilleengen if (gc->lg_name == NULL) {
284e8f6ee4aSJaakko Heinonen mt->error = errno;
285e8f6ee4aSJaakko Heinonen XML_StopParser(mt->parser, 0);
2867b6942a1SUlf Lilleengen warn("Cannot allocate memory during processing of '%s' "
2877b6942a1SUlf Lilleengen "element", name);
288ef9fc4afSXin LI free(gc);
289ef9fc4afSXin LI free(p);
2907b6942a1SUlf Lilleengen return;
2917b6942a1SUlf Lilleengen }
2920aedf4e8SAlexander Motin gc->lg_val = p;
2935523c82cSAlexander Motin LIST_INSERT_HEAD(c, gc, lg_config);
2947bd4e7b4SPoul-Henning Kamp return;
2957bd4e7b4SPoul-Henning Kamp }
2967bd4e7b4SPoul-Henning Kamp
2977bd4e7b4SPoul-Henning Kamp if (p != NULL) {
298748e404fSScott Long #if DEBUG_LIBGEOM > 0
2992ad2651aSPoul-Henning Kamp printf("Unexpected XML: name=%s data=\"%s\"\n", name, p);
300748e404fSScott Long #endif
3017bd4e7b4SPoul-Henning Kamp free(p);
3027bd4e7b4SPoul-Henning Kamp }
3037bd4e7b4SPoul-Henning Kamp
3047bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "consumer") && mt->consumer != NULL) {
3057bd4e7b4SPoul-Henning Kamp mt->consumer = NULL;
3067bd4e7b4SPoul-Henning Kamp return;
3077bd4e7b4SPoul-Henning Kamp }
3087bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "provider") && mt->provider != NULL) {
3097bd4e7b4SPoul-Henning Kamp mt->provider = NULL;
3107bd4e7b4SPoul-Henning Kamp return;
3117bd4e7b4SPoul-Henning Kamp }
3127bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "geom") && mt->consumer != NULL) {
3137bd4e7b4SPoul-Henning Kamp return;
3147bd4e7b4SPoul-Henning Kamp }
3157bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "geom") && mt->provider != NULL) {
3167bd4e7b4SPoul-Henning Kamp return;
3177bd4e7b4SPoul-Henning Kamp }
3187bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "geom") && mt->geom != NULL) {
3197bd4e7b4SPoul-Henning Kamp mt->geom = NULL;
3207bd4e7b4SPoul-Henning Kamp return;
3217bd4e7b4SPoul-Henning Kamp }
3227bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "class") && mt->geom != NULL) {
3237bd4e7b4SPoul-Henning Kamp return;
3247bd4e7b4SPoul-Henning Kamp }
3257bd4e7b4SPoul-Henning Kamp if (!strcmp(name, "class") && mt->class != NULL) {
3267bd4e7b4SPoul-Henning Kamp mt->class = NULL;
3277bd4e7b4SPoul-Henning Kamp return;
3287bd4e7b4SPoul-Henning Kamp }
3297bd4e7b4SPoul-Henning Kamp }
3307bd4e7b4SPoul-Henning Kamp
3317bd4e7b4SPoul-Henning Kamp static void
CharData(void * userData,const XML_Char * s,int len)3327bd4e7b4SPoul-Henning Kamp CharData(void *userData , const XML_Char *s , int len)
3337bd4e7b4SPoul-Henning Kamp {
3347bd4e7b4SPoul-Henning Kamp struct mystate *mt;
3357bd4e7b4SPoul-Henning Kamp const char *b, *e;
3367bd4e7b4SPoul-Henning Kamp
3377bd4e7b4SPoul-Henning Kamp mt = userData;
3387bd4e7b4SPoul-Henning Kamp
3397bd4e7b4SPoul-Henning Kamp b = s;
3407bd4e7b4SPoul-Henning Kamp e = s + len - 1;
3417bd4e7b4SPoul-Henning Kamp while (isspace(*b) && b < e)
3427bd4e7b4SPoul-Henning Kamp b++;
3437bd4e7b4SPoul-Henning Kamp while (isspace(*e) && e > b)
3447bd4e7b4SPoul-Henning Kamp e--;
3457bd4e7b4SPoul-Henning Kamp if (e != b || (*b && !isspace(*b)))
3467bd4e7b4SPoul-Henning Kamp sbuf_bcat(mt->sbuf[mt->level], b, e - b + 1);
3477bd4e7b4SPoul-Henning Kamp }
3487bd4e7b4SPoul-Henning Kamp
3497bd4e7b4SPoul-Henning Kamp struct gident *
geom_lookupid(struct gmesh * gmp,const void * id)3502ad2651aSPoul-Henning Kamp geom_lookupid(struct gmesh *gmp, const void *id)
3517bd4e7b4SPoul-Henning Kamp {
352019100deSJuli Mallett struct gident *gip;
3537bd4e7b4SPoul-Henning Kamp
354019100deSJuli Mallett for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++)
355019100deSJuli Mallett if (gip->lg_id == id)
356019100deSJuli Mallett return (gip);
3577bd4e7b4SPoul-Henning Kamp return (NULL);
3587bd4e7b4SPoul-Henning Kamp }
3597bd4e7b4SPoul-Henning Kamp
3607f16b501SAlexander Motin static void *
geom_lookupidptr(struct gmesh * gmp,const void * id)3617f16b501SAlexander Motin geom_lookupidptr(struct gmesh *gmp, const void *id)
3627f16b501SAlexander Motin {
3637f16b501SAlexander Motin struct gident *gip;
3647f16b501SAlexander Motin
3657f16b501SAlexander Motin gip = geom_lookupid(gmp, id);
3667f16b501SAlexander Motin if (gip)
3677f16b501SAlexander Motin return (gip->lg_ptr);
3687f16b501SAlexander Motin return (NULL);
3697f16b501SAlexander Motin }
3707f16b501SAlexander Motin
3717bd4e7b4SPoul-Henning Kamp int
geom_xml2tree(struct gmesh * gmp,char * p)3727bd4e7b4SPoul-Henning Kamp geom_xml2tree(struct gmesh *gmp, char *p)
3737bd4e7b4SPoul-Henning Kamp {
3747bd4e7b4SPoul-Henning Kamp XML_Parser parser;
3757bd4e7b4SPoul-Henning Kamp struct mystate *mt;
3767bd4e7b4SPoul-Henning Kamp struct gclass *cl;
3777bd4e7b4SPoul-Henning Kamp struct ggeom *ge;
3787bd4e7b4SPoul-Henning Kamp struct gprovider *pr;
3797bd4e7b4SPoul-Henning Kamp struct gconsumer *co;
380e8f6ee4aSJaakko Heinonen int error, i;
3817bd4e7b4SPoul-Henning Kamp
3827bd4e7b4SPoul-Henning Kamp memset(gmp, 0, sizeof *gmp);
383ccac9da4SJohn Baldwin LIST_INIT(&gmp->lg_class);
3847bd4e7b4SPoul-Henning Kamp parser = XML_ParserCreate(NULL);
3852cf6dafaSEd Maste if (parser == NULL)
3867bd4e7b4SPoul-Henning Kamp return (ENOMEM);
3872cf6dafaSEd Maste mt = calloc(1, sizeof *mt);
3882cf6dafaSEd Maste if (mt == NULL) {
3892cf6dafaSEd Maste XML_ParserFree(parser);
3902cf6dafaSEd Maste return (ENOMEM);
3912cf6dafaSEd Maste }
3927bd4e7b4SPoul-Henning Kamp mt->mesh = gmp;
393e8f6ee4aSJaakko Heinonen mt->parser = parser;
394e8f6ee4aSJaakko Heinonen error = 0;
3957bd4e7b4SPoul-Henning Kamp XML_SetUserData(parser, mt);
3967bd4e7b4SPoul-Henning Kamp XML_SetElementHandler(parser, StartElement, EndElement);
3977bd4e7b4SPoul-Henning Kamp XML_SetCharacterDataHandler(parser, CharData);
3987bd4e7b4SPoul-Henning Kamp i = XML_Parse(parser, p, strlen(p), 1);
399e8f6ee4aSJaakko Heinonen if (mt->error != 0)
400e8f6ee4aSJaakko Heinonen error = mt->error;
401e8f6ee4aSJaakko Heinonen else if (i != 1) {
402e8f6ee4aSJaakko Heinonen error = XML_GetErrorCode(parser) == XML_ERROR_NO_MEMORY ?
403e8f6ee4aSJaakko Heinonen ENOMEM : EILSEQ;
404e8f6ee4aSJaakko Heinonen }
4057bd4e7b4SPoul-Henning Kamp XML_ParserFree(parser);
406e8f6ee4aSJaakko Heinonen if (error != 0) {
4072cf6dafaSEd Maste free(mt);
408e8f6ee4aSJaakko Heinonen return (error);
4092cf6dafaSEd Maste }
410*bf3b889aSJohn Baldwin gmp->lg_ident = calloc(mt->nident + 1, sizeof(*gmp->lg_ident));
4112cf6dafaSEd Maste free(mt);
412019100deSJuli Mallett if (gmp->lg_ident == NULL)
4137bd4e7b4SPoul-Henning Kamp return (ENOMEM);
414019100deSJuli Mallett i = 0;
4157bd4e7b4SPoul-Henning Kamp /* Collect all identifiers */
416ccac9da4SJohn Baldwin LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
417019100deSJuli Mallett gmp->lg_ident[i].lg_id = cl->lg_id;
418019100deSJuli Mallett gmp->lg_ident[i].lg_ptr = cl;
419019100deSJuli Mallett gmp->lg_ident[i].lg_what = ISCLASS;
420019100deSJuli Mallett i++;
421ccac9da4SJohn Baldwin LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
422019100deSJuli Mallett gmp->lg_ident[i].lg_id = ge->lg_id;
423019100deSJuli Mallett gmp->lg_ident[i].lg_ptr = ge;
424019100deSJuli Mallett gmp->lg_ident[i].lg_what = ISGEOM;
425019100deSJuli Mallett i++;
426ccac9da4SJohn Baldwin LIST_FOREACH(pr, &ge->lg_provider, lg_provider) {
427019100deSJuli Mallett gmp->lg_ident[i].lg_id = pr->lg_id;
428019100deSJuli Mallett gmp->lg_ident[i].lg_ptr = pr;
429019100deSJuli Mallett gmp->lg_ident[i].lg_what = ISPROVIDER;
430019100deSJuli Mallett i++;
4317bd4e7b4SPoul-Henning Kamp }
432ccac9da4SJohn Baldwin LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
433019100deSJuli Mallett gmp->lg_ident[i].lg_id = co->lg_id;
434019100deSJuli Mallett gmp->lg_ident[i].lg_ptr = co;
435019100deSJuli Mallett gmp->lg_ident[i].lg_what = ISCONSUMER;
436019100deSJuli Mallett i++;
4377bd4e7b4SPoul-Henning Kamp }
4387bd4e7b4SPoul-Henning Kamp }
4397bd4e7b4SPoul-Henning Kamp }
4407bd4e7b4SPoul-Henning Kamp /* Substitute all identifiers */
441ccac9da4SJohn Baldwin LIST_FOREACH(cl, &gmp->lg_class, lg_class) {
442ccac9da4SJohn Baldwin LIST_FOREACH(ge, &cl->lg_geom, lg_geom) {
4437f16b501SAlexander Motin ge->lg_class = geom_lookupidptr(gmp, ge->lg_class);
4447f16b501SAlexander Motin LIST_FOREACH(pr, &ge->lg_provider, lg_provider)
4457f16b501SAlexander Motin pr->lg_geom = geom_lookupidptr(gmp, pr->lg_geom);
446ccac9da4SJohn Baldwin LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) {
4477f16b501SAlexander Motin co->lg_geom = geom_lookupidptr(gmp, co->lg_geom);
448ccac9da4SJohn Baldwin if (co->lg_provider != NULL) {
4497f16b501SAlexander Motin co->lg_provider = geom_lookupidptr(gmp,
4507f16b501SAlexander Motin co->lg_provider);
4517f16b501SAlexander Motin if (co->lg_provider != NULL) {
4524aa50d28SPoul-Henning Kamp LIST_INSERT_HEAD(
453ccac9da4SJohn Baldwin &co->lg_provider->lg_consumers,
454ccac9da4SJohn Baldwin co, lg_consumers);
4554aa50d28SPoul-Henning Kamp }
4567bd4e7b4SPoul-Henning Kamp }
4577bd4e7b4SPoul-Henning Kamp }
4587bd4e7b4SPoul-Henning Kamp }
4597f16b501SAlexander Motin }
4607bd4e7b4SPoul-Henning Kamp return (0);
4617bd4e7b4SPoul-Henning Kamp }
4627bd4e7b4SPoul-Henning Kamp
4637bd4e7b4SPoul-Henning Kamp int
geom_gettree(struct gmesh * gmp)4647bd4e7b4SPoul-Henning Kamp geom_gettree(struct gmesh *gmp)
4657bd4e7b4SPoul-Henning Kamp {
4667bd4e7b4SPoul-Henning Kamp char *p;
4677bd4e7b4SPoul-Henning Kamp int error;
4687bd4e7b4SPoul-Henning Kamp
4697bd4e7b4SPoul-Henning Kamp p = geom_getxml();
47090d93f71SPoul-Henning Kamp if (p == NULL)
47190d93f71SPoul-Henning Kamp return (errno);
4727bd4e7b4SPoul-Henning Kamp error = geom_xml2tree(gmp, p);
4737bd4e7b4SPoul-Henning Kamp free(p);
4747bd4e7b4SPoul-Henning Kamp return (error);
4757bd4e7b4SPoul-Henning Kamp }
4767bd4e7b4SPoul-Henning Kamp
4777f16b501SAlexander Motin int
geom_gettree_geom(struct gmesh * gmp,const char * c,const char * g,int parents)4787f16b501SAlexander Motin geom_gettree_geom(struct gmesh *gmp, const char *c, const char *g, int parents)
4797f16b501SAlexander Motin {
4807f16b501SAlexander Motin char *p;
4817f16b501SAlexander Motin int error;
4827f16b501SAlexander Motin
483bd0f3d34SAlexander Motin if (g != NULL && strncmp(g, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
484bd0f3d34SAlexander Motin g += sizeof(_PATH_DEV) - 1;
4857f16b501SAlexander Motin p = geom_getxml_geom(c, g, parents);
4867f16b501SAlexander Motin if (p == NULL)
4877f16b501SAlexander Motin return (errno);
4887f16b501SAlexander Motin error = geom_xml2tree(gmp, p);
4897f16b501SAlexander Motin free(p);
4907f16b501SAlexander Motin return (error);
4917f16b501SAlexander Motin }
4927f16b501SAlexander Motin
4937bd4e7b4SPoul-Henning Kamp static void
delete_config(struct gconf * gp)4947bd4e7b4SPoul-Henning Kamp delete_config(struct gconf *gp)
4957bd4e7b4SPoul-Henning Kamp {
4967bd4e7b4SPoul-Henning Kamp struct gconfig *cf;
4977bd4e7b4SPoul-Henning Kamp
4987bd4e7b4SPoul-Henning Kamp for (;;) {
4997bd4e7b4SPoul-Henning Kamp cf = LIST_FIRST(gp);
5007bd4e7b4SPoul-Henning Kamp if (cf == NULL)
5017bd4e7b4SPoul-Henning Kamp return;
502ccac9da4SJohn Baldwin LIST_REMOVE(cf, lg_config);
503ccac9da4SJohn Baldwin free(cf->lg_name);
504ccac9da4SJohn Baldwin free(cf->lg_val);
5057bd4e7b4SPoul-Henning Kamp free(cf);
5067bd4e7b4SPoul-Henning Kamp }
5077bd4e7b4SPoul-Henning Kamp }
5087bd4e7b4SPoul-Henning Kamp
5097bd4e7b4SPoul-Henning Kamp void
geom_deletetree(struct gmesh * gmp)5107bd4e7b4SPoul-Henning Kamp geom_deletetree(struct gmesh *gmp)
5117bd4e7b4SPoul-Henning Kamp {
5127bd4e7b4SPoul-Henning Kamp struct gclass *cl;
5137bd4e7b4SPoul-Henning Kamp struct ggeom *ge;
5147bd4e7b4SPoul-Henning Kamp struct gprovider *pr;
5157bd4e7b4SPoul-Henning Kamp struct gconsumer *co;
5167bd4e7b4SPoul-Henning Kamp
517ccac9da4SJohn Baldwin free(gmp->lg_ident);
518ccac9da4SJohn Baldwin gmp->lg_ident = NULL;
5197bd4e7b4SPoul-Henning Kamp for (;;) {
520ccac9da4SJohn Baldwin cl = LIST_FIRST(&gmp->lg_class);
5217bd4e7b4SPoul-Henning Kamp if (cl == NULL)
5227bd4e7b4SPoul-Henning Kamp break;
523ccac9da4SJohn Baldwin LIST_REMOVE(cl, lg_class);
524ccac9da4SJohn Baldwin delete_config(&cl->lg_config);
525ccac9da4SJohn Baldwin if (cl->lg_name) free(cl->lg_name);
5267bd4e7b4SPoul-Henning Kamp for (;;) {
527ccac9da4SJohn Baldwin ge = LIST_FIRST(&cl->lg_geom);
5287bd4e7b4SPoul-Henning Kamp if (ge == NULL)
5297bd4e7b4SPoul-Henning Kamp break;
530ccac9da4SJohn Baldwin LIST_REMOVE(ge, lg_geom);
531ccac9da4SJohn Baldwin delete_config(&ge->lg_config);
532ccac9da4SJohn Baldwin if (ge->lg_name) free(ge->lg_name);
5337bd4e7b4SPoul-Henning Kamp for (;;) {
534ccac9da4SJohn Baldwin pr = LIST_FIRST(&ge->lg_provider);
5357bd4e7b4SPoul-Henning Kamp if (pr == NULL)
5367bd4e7b4SPoul-Henning Kamp break;
537ccac9da4SJohn Baldwin LIST_REMOVE(pr, lg_provider);
538ccac9da4SJohn Baldwin delete_config(&pr->lg_config);
539ccac9da4SJohn Baldwin if (pr->lg_name) free(pr->lg_name);
540ccac9da4SJohn Baldwin if (pr->lg_mode) free(pr->lg_mode);
5417bd4e7b4SPoul-Henning Kamp free(pr);
5427bd4e7b4SPoul-Henning Kamp }
5437bd4e7b4SPoul-Henning Kamp for (;;) {
544ccac9da4SJohn Baldwin co = LIST_FIRST(&ge->lg_consumer);
5457bd4e7b4SPoul-Henning Kamp if (co == NULL)
5467bd4e7b4SPoul-Henning Kamp break;
547ccac9da4SJohn Baldwin LIST_REMOVE(co, lg_consumer);
548ccac9da4SJohn Baldwin delete_config(&co->lg_config);
549ccac9da4SJohn Baldwin if (co->lg_mode) free(co->lg_mode);
5507bd4e7b4SPoul-Henning Kamp free(co);
5517bd4e7b4SPoul-Henning Kamp }
5527bd4e7b4SPoul-Henning Kamp free(ge);
5537bd4e7b4SPoul-Henning Kamp }
5547bd4e7b4SPoul-Henning Kamp free(cl);
5557bd4e7b4SPoul-Henning Kamp }
5567bd4e7b4SPoul-Henning Kamp }
557