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 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 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 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 * 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 * 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 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 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 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 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 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