1110603Sphk/*- 2110603Sphk * Copyright (c) 2003 Poul-Henning Kamp 3110603Sphk * All rights reserved. 4110603Sphk * 5110603Sphk * Redistribution and use in source and binary forms, with or without 6110603Sphk * modification, are permitted provided that the following conditions 7110603Sphk * are met: 8110603Sphk * 1. Redistributions of source code must retain the above copyright 9110603Sphk * notice, this list of conditions and the following disclaimer. 10110603Sphk * 2. Redistributions in binary form must reproduce the above copyright 11110603Sphk * notice, this list of conditions and the following disclaimer in the 12110603Sphk * documentation and/or other materials provided with the distribution. 13110603Sphk * 3. The names of the authors may not be used to endorse or promote 14110603Sphk * products derived from this software without specific prior written 15110603Sphk * permission. 16110603Sphk * 17110603Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18110603Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19110603Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20110603Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21110603Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22110603Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23110603Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24110603Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25110603Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26110603Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27110603Sphk * SUCH DAMAGE. 28110603Sphk * 29110603Sphk * $FreeBSD: releng/10.3/lib/libgeom/geom_xml2tree.c 287792 2015-09-14 18:05:27Z delphij $ 30110603Sphk */ 31110603Sphk 32110603Sphk#include <stdio.h> 33110603Sphk#include <inttypes.h> 34110603Sphk#include <stdlib.h> 35110603Sphk#include <string.h> 36110603Sphk#include <unistd.h> 37110603Sphk#include <errno.h> 38110603Sphk#include <fcntl.h> 39110603Sphk#include <ctype.h> 40110603Sphk#include <sys/stat.h> 41110603Sphk#include <sys/mman.h> 42110603Sphk#include <sys/queue.h> 43110603Sphk#include <sys/sbuf.h> 44110603Sphk#include <sys/sysctl.h> 45110603Sphk#include <err.h> 46110603Sphk#include <bsdxml.h> 47110603Sphk#include <libgeom.h> 48110603Sphk 49110603Sphkstruct mystate { 50110603Sphk struct gmesh *mesh; 51110603Sphk struct gclass *class; 52110603Sphk struct ggeom *geom; 53110603Sphk struct gprovider *provider; 54110603Sphk struct gconsumer *consumer; 55110603Sphk int level; 56110603Sphk struct sbuf *sbuf[20]; 57110603Sphk struct gconf *config; 58234107Sjmallett int nident; 59242130Sjh XML_Parser parser; 60242130Sjh int error; 61110603Sphk}; 62110603Sphk 63110603Sphkstatic void 64110603SphkStartElement(void *userData, const char *name, const char **attr) 65110603Sphk{ 66110603Sphk struct mystate *mt; 67110603Sphk void *id; 68110603Sphk void *ref; 69110603Sphk int i; 70110603Sphk 71110603Sphk mt = userData; 72110603Sphk mt->level++; 73181463Sdes mt->sbuf[mt->level] = sbuf_new_auto(); 74110603Sphk id = NULL; 75126786Sjhb ref = NULL; 76110603Sphk for (i = 0; attr[i] != NULL; i += 2) { 77110603Sphk if (!strcmp(attr[i], "id")) { 78253249Shrs id = (void *)strtoul(attr[i + 1], NULL, 0); 79234107Sjmallett mt->nident++; 80110603Sphk } else if (!strcmp(attr[i], "ref")) { 81253249Shrs ref = (void *)strtoul(attr[i + 1], NULL, 0); 82110603Sphk } else 83110603Sphk printf("%*.*s[%s = %s]\n", 84110603Sphk mt->level + 1, mt->level + 1, "", 85110603Sphk attr[i], attr[i + 1]); 86110603Sphk } 87110603Sphk if (!strcmp(name, "class") && mt->class == NULL) { 88110603Sphk mt->class = calloc(1, sizeof *mt->class); 89180369Slulf if (mt->class == NULL) { 90242130Sjh mt->error = errno; 91242130Sjh XML_StopParser(mt->parser, 0); 92180369Slulf warn("Cannot allocate memory during processing of '%s' " 93180369Slulf "element", name); 94180369Slulf return; 95180369Slulf } 96126786Sjhb mt->class->lg_id = id; 97126786Sjhb LIST_INSERT_HEAD(&mt->mesh->lg_class, mt->class, lg_class); 98126786Sjhb LIST_INIT(&mt->class->lg_geom); 99126786Sjhb LIST_INIT(&mt->class->lg_config); 100110603Sphk return; 101110603Sphk } 102110603Sphk if (!strcmp(name, "geom") && mt->geom == NULL) { 103110603Sphk mt->geom = calloc(1, sizeof *mt->geom); 104180369Slulf if (mt->geom == NULL) { 105242130Sjh mt->error = errno; 106242130Sjh XML_StopParser(mt->parser, 0); 107180369Slulf warn("Cannot allocate memory during processing of '%s' " 108180369Slulf "element", name); 109180369Slulf return; 110180369Slulf } 111126786Sjhb mt->geom->lg_id = id; 112126786Sjhb LIST_INSERT_HEAD(&mt->class->lg_geom, mt->geom, lg_geom); 113126786Sjhb LIST_INIT(&mt->geom->lg_provider); 114126786Sjhb LIST_INIT(&mt->geom->lg_consumer); 115126786Sjhb LIST_INIT(&mt->geom->lg_config); 116110603Sphk return; 117110603Sphk } 118110603Sphk if (!strcmp(name, "class") && mt->geom != NULL) { 119126786Sjhb mt->geom->lg_class = ref; 120110603Sphk return; 121110603Sphk } 122110603Sphk if (!strcmp(name, "consumer") && mt->consumer == NULL) { 123110603Sphk mt->consumer = calloc(1, sizeof *mt->consumer); 124180369Slulf if (mt->consumer == NULL) { 125242130Sjh mt->error = errno; 126242130Sjh XML_StopParser(mt->parser, 0); 127180369Slulf warn("Cannot allocate memory during processing of '%s' " 128180369Slulf "element", name); 129180369Slulf return; 130180369Slulf } 131126786Sjhb mt->consumer->lg_id = id; 132126786Sjhb LIST_INSERT_HEAD(&mt->geom->lg_consumer, mt->consumer, 133126786Sjhb lg_consumer); 134126786Sjhb LIST_INIT(&mt->consumer->lg_config); 135110603Sphk return; 136110603Sphk } 137110603Sphk if (!strcmp(name, "geom") && mt->consumer != NULL) { 138126786Sjhb mt->consumer->lg_geom = ref; 139110603Sphk return; 140110603Sphk } 141110603Sphk if (!strcmp(name, "provider") && mt->consumer != NULL) { 142126786Sjhb mt->consumer->lg_provider = ref; 143110603Sphk return; 144110603Sphk } 145110603Sphk if (!strcmp(name, "provider") && mt->provider == NULL) { 146110603Sphk mt->provider = calloc(1, sizeof *mt->provider); 147180369Slulf if (mt->provider == NULL) { 148242130Sjh mt->error = errno; 149242130Sjh XML_StopParser(mt->parser, 0); 150180369Slulf warn("Cannot allocate memory during processing of '%s' " 151180369Slulf "element", name); 152180369Slulf return; 153180369Slulf } 154126786Sjhb mt->provider->lg_id = id; 155126786Sjhb LIST_INSERT_HEAD(&mt->geom->lg_provider, mt->provider, 156126786Sjhb lg_provider); 157126786Sjhb LIST_INIT(&mt->provider->lg_consumers); 158126786Sjhb LIST_INIT(&mt->provider->lg_config); 159110603Sphk return; 160110603Sphk } 161110603Sphk if (!strcmp(name, "geom") && mt->provider != NULL) { 162126786Sjhb mt->provider->lg_geom = ref; 163110603Sphk return; 164110603Sphk } 165110603Sphk if (!strcmp(name, "config")) { 166110603Sphk if (mt->provider != NULL) { 167126786Sjhb mt->config = &mt->provider->lg_config; 168110603Sphk return; 169110603Sphk } 170110603Sphk if (mt->consumer != NULL) { 171126786Sjhb mt->config = &mt->consumer->lg_config; 172110603Sphk return; 173110603Sphk } 174110603Sphk if (mt->geom != NULL) { 175126786Sjhb mt->config = &mt->geom->lg_config; 176110603Sphk return; 177110603Sphk } 178110603Sphk if (mt->class != NULL) { 179126786Sjhb mt->config = &mt->class->lg_config; 180110603Sphk return; 181110603Sphk } 182110603Sphk } 183110603Sphk} 184110603Sphk 185110603Sphkstatic void 186110603SphkEndElement(void *userData, const char *name) 187110603Sphk{ 188110603Sphk struct mystate *mt; 189281303Smav struct gconf *c; 190110603Sphk struct gconfig *gc; 191110603Sphk char *p; 192110603Sphk 193110603Sphk mt = userData; 194242130Sjh p = NULL; 195242130Sjh if (sbuf_finish(mt->sbuf[mt->level]) == 0) 196242130Sjh p = strdup(sbuf_data(mt->sbuf[mt->level])); 197242130Sjh sbuf_delete(mt->sbuf[mt->level]); 198242130Sjh mt->sbuf[mt->level] = NULL; 199242130Sjh mt->level--; 200180369Slulf if (p == NULL) { 201242130Sjh mt->error = errno; 202242130Sjh XML_StopParser(mt->parser, 0); 203180369Slulf warn("Cannot allocate memory during processing of '%s' " 204180369Slulf "element", name); 205180369Slulf return; 206180369Slulf } 207110603Sphk if (strlen(p) == 0) { 208110603Sphk free(p); 209110603Sphk p = NULL; 210110603Sphk } 211110603Sphk 212110603Sphk if (!strcmp(name, "name")) { 213110603Sphk if (mt->provider != NULL) { 214126786Sjhb mt->provider->lg_name = p; 215110603Sphk return; 216110603Sphk } else if (mt->geom != NULL) { 217126786Sjhb mt->geom->lg_name = p; 218110603Sphk return; 219110603Sphk } else if (mt->class != NULL) { 220126786Sjhb mt->class->lg_name = p; 221110603Sphk return; 222110603Sphk } 223110603Sphk } 224110603Sphk if (!strcmp(name, "rank") && mt->geom != NULL) { 225126786Sjhb mt->geom->lg_rank = strtoul(p, NULL, 0); 226110603Sphk free(p); 227110603Sphk return; 228110603Sphk } 229110603Sphk if (!strcmp(name, "mode") && mt->provider != NULL) { 230126786Sjhb mt->provider->lg_mode = p; 231110603Sphk return; 232110603Sphk } 233110603Sphk if (!strcmp(name, "mode") && mt->consumer != NULL) { 234126786Sjhb mt->consumer->lg_mode = p; 235110603Sphk return; 236110603Sphk } 237110603Sphk if (!strcmp(name, "mediasize") && mt->provider != NULL) { 238126786Sjhb mt->provider->lg_mediasize = strtoumax(p, NULL, 0); 239110603Sphk free(p); 240110603Sphk return; 241110603Sphk } 242110603Sphk if (!strcmp(name, "sectorsize") && mt->provider != NULL) { 243126786Sjhb mt->provider->lg_sectorsize = strtoul(p, NULL, 0); 244110603Sphk free(p); 245110603Sphk return; 246110603Sphk } 247202454Sdelphij if (!strcmp(name, "stripesize") && mt->provider != NULL) { 248202454Sdelphij mt->provider->lg_stripesize = strtoumax(p, NULL, 0); 249202454Sdelphij free(p); 250202454Sdelphij return; 251202454Sdelphij } 252202454Sdelphij if (!strcmp(name, "stripeoffset") && mt->provider != NULL) { 253202454Sdelphij mt->provider->lg_stripeoffset = strtoumax(p, NULL, 0); 254202454Sdelphij free(p); 255202454Sdelphij return; 256202454Sdelphij } 257110603Sphk 258110603Sphk if (!strcmp(name, "config")) { 259110603Sphk mt->config = NULL; 260282222Spfg free(p); 261110603Sphk return; 262110603Sphk } 263110603Sphk 264281303Smav if (mt->config != NULL || (!strcmp(name, "wither") && 265281303Smav (mt->provider != NULL || mt->geom != NULL))) { 266281303Smav if (mt->config != NULL) 267281303Smav c = mt->config; 268281303Smav else if (mt->provider != NULL) 269281303Smav c = &mt->provider->lg_config; 270281303Smav else 271281303Smav c = &mt->geom->lg_config; 272180369Slulf gc = calloc(1, sizeof *gc); 273180369Slulf if (gc == NULL) { 274242130Sjh mt->error = errno; 275242130Sjh XML_StopParser(mt->parser, 0); 276180369Slulf warn("Cannot allocate memory during processing of '%s' " 277180369Slulf "element", name); 278287792Sdelphij free(p); 279180369Slulf return; 280180369Slulf } 281126786Sjhb gc->lg_name = strdup(name); 282180369Slulf if (gc->lg_name == NULL) { 283242130Sjh mt->error = errno; 284242130Sjh XML_StopParser(mt->parser, 0); 285180369Slulf warn("Cannot allocate memory during processing of '%s' " 286180369Slulf "element", name); 287287792Sdelphij free(gc); 288287792Sdelphij free(p); 289180369Slulf return; 290180369Slulf } 291286819Smav gc->lg_val = p; 292281303Smav LIST_INSERT_HEAD(c, gc, lg_config); 293110603Sphk return; 294110603Sphk } 295110603Sphk 296110603Sphk if (p != NULL) { 297253469Sscottl#if DEBUG_LIBGEOM > 0 298112340Sphk printf("Unexpected XML: name=%s data=\"%s\"\n", name, p); 299253469Sscottl#endif 300110603Sphk free(p); 301110603Sphk } 302110603Sphk 303110603Sphk if (!strcmp(name, "consumer") && mt->consumer != NULL) { 304110603Sphk mt->consumer = NULL; 305110603Sphk return; 306110603Sphk } 307110603Sphk if (!strcmp(name, "provider") && mt->provider != NULL) { 308110603Sphk mt->provider = NULL; 309110603Sphk return; 310110603Sphk } 311110603Sphk if (!strcmp(name, "geom") && mt->consumer != NULL) { 312110603Sphk return; 313110603Sphk } 314110603Sphk if (!strcmp(name, "geom") && mt->provider != NULL) { 315110603Sphk return; 316110603Sphk } 317110603Sphk if (!strcmp(name, "geom") && mt->geom != NULL) { 318110603Sphk mt->geom = NULL; 319110603Sphk return; 320110603Sphk } 321110603Sphk if (!strcmp(name, "class") && mt->geom != NULL) { 322110603Sphk return; 323110603Sphk } 324110603Sphk if (!strcmp(name, "class") && mt->class != NULL) { 325110603Sphk mt->class = NULL; 326110603Sphk return; 327110603Sphk } 328110603Sphk} 329110603Sphk 330110603Sphkstatic void 331110603SphkCharData(void *userData , const XML_Char *s , int len) 332110603Sphk{ 333110603Sphk struct mystate *mt; 334110603Sphk const char *b, *e; 335110603Sphk 336110603Sphk mt = userData; 337110603Sphk 338110603Sphk b = s; 339110603Sphk e = s + len - 1; 340110603Sphk while (isspace(*b) && b < e) 341110603Sphk b++; 342110603Sphk while (isspace(*e) && e > b) 343110603Sphk e--; 344110603Sphk if (e != b || (*b && !isspace(*b))) 345110603Sphk sbuf_bcat(mt->sbuf[mt->level], b, e - b + 1); 346110603Sphk} 347110603Sphk 348110603Sphkstruct gident * 349112340Sphkgeom_lookupid(struct gmesh *gmp, const void *id) 350110603Sphk{ 351234107Sjmallett struct gident *gip; 352110603Sphk 353234107Sjmallett for (gip = gmp->lg_ident; gip->lg_id != NULL; gip++) 354234107Sjmallett if (gip->lg_id == id) 355234107Sjmallett return (gip); 356110603Sphk return (NULL); 357110603Sphk} 358110603Sphk 359110603Sphkint 360110603Sphkgeom_xml2tree(struct gmesh *gmp, char *p) 361110603Sphk{ 362110603Sphk XML_Parser parser; 363110603Sphk struct mystate *mt; 364110603Sphk struct gclass *cl; 365110603Sphk struct ggeom *ge; 366110603Sphk struct gprovider *pr; 367110603Sphk struct gconsumer *co; 368242130Sjh int error, i; 369110603Sphk 370110603Sphk memset(gmp, 0, sizeof *gmp); 371126786Sjhb LIST_INIT(&gmp->lg_class); 372110603Sphk parser = XML_ParserCreate(NULL); 373213451Semaste if (parser == NULL) 374213451Semaste return (ENOMEM); 375110603Sphk mt = calloc(1, sizeof *mt); 376213451Semaste if (mt == NULL) { 377213451Semaste XML_ParserFree(parser); 378110603Sphk return (ENOMEM); 379213451Semaste } 380110603Sphk mt->mesh = gmp; 381242130Sjh mt->parser = parser; 382242130Sjh error = 0; 383110603Sphk XML_SetUserData(parser, mt); 384110603Sphk XML_SetElementHandler(parser, StartElement, EndElement); 385110603Sphk XML_SetCharacterDataHandler(parser, CharData); 386110603Sphk i = XML_Parse(parser, p, strlen(p), 1); 387242130Sjh if (mt->error != 0) 388242130Sjh error = mt->error; 389242130Sjh else if (i != 1) { 390242130Sjh error = XML_GetErrorCode(parser) == XML_ERROR_NO_MEMORY ? 391242130Sjh ENOMEM : EILSEQ; 392242130Sjh } 393213451Semaste XML_ParserFree(parser); 394242130Sjh if (error != 0) { 395213451Semaste free(mt); 396242130Sjh return (error); 397213451Semaste } 398234107Sjmallett gmp->lg_ident = calloc(sizeof *gmp->lg_ident, mt->nident + 1); 399234107Sjmallett free(mt); 400234107Sjmallett if (gmp->lg_ident == NULL) 401233646Sjmallett return (ENOMEM); 402234107Sjmallett i = 0; 403110603Sphk /* Collect all identifiers */ 404126786Sjhb LIST_FOREACH(cl, &gmp->lg_class, lg_class) { 405234107Sjmallett gmp->lg_ident[i].lg_id = cl->lg_id; 406234107Sjmallett gmp->lg_ident[i].lg_ptr = cl; 407234107Sjmallett gmp->lg_ident[i].lg_what = ISCLASS; 408234107Sjmallett i++; 409126786Sjhb LIST_FOREACH(ge, &cl->lg_geom, lg_geom) { 410234107Sjmallett gmp->lg_ident[i].lg_id = ge->lg_id; 411234107Sjmallett gmp->lg_ident[i].lg_ptr = ge; 412234107Sjmallett gmp->lg_ident[i].lg_what = ISGEOM; 413234107Sjmallett i++; 414126786Sjhb LIST_FOREACH(pr, &ge->lg_provider, lg_provider) { 415234107Sjmallett gmp->lg_ident[i].lg_id = pr->lg_id; 416234107Sjmallett gmp->lg_ident[i].lg_ptr = pr; 417234107Sjmallett gmp->lg_ident[i].lg_what = ISPROVIDER; 418234107Sjmallett i++; 419110603Sphk } 420126786Sjhb LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) { 421234107Sjmallett gmp->lg_ident[i].lg_id = co->lg_id; 422234107Sjmallett gmp->lg_ident[i].lg_ptr = co; 423234107Sjmallett gmp->lg_ident[i].lg_what = ISCONSUMER; 424234107Sjmallett i++; 425110603Sphk } 426110603Sphk } 427110603Sphk } 428110603Sphk /* Substitute all identifiers */ 429126786Sjhb LIST_FOREACH(cl, &gmp->lg_class, lg_class) { 430126786Sjhb LIST_FOREACH(ge, &cl->lg_geom, lg_geom) { 431126786Sjhb ge->lg_class = 432126786Sjhb geom_lookupid(gmp, ge->lg_class)->lg_ptr; 433126786Sjhb LIST_FOREACH(pr, &ge->lg_provider, lg_provider) { 434126786Sjhb pr->lg_geom = 435126786Sjhb geom_lookupid(gmp, pr->lg_geom)->lg_ptr; 436110603Sphk } 437126786Sjhb LIST_FOREACH(co, &ge->lg_consumer, lg_consumer) { 438126786Sjhb co->lg_geom = 439126786Sjhb geom_lookupid(gmp, co->lg_geom)->lg_ptr; 440126786Sjhb if (co->lg_provider != NULL) { 441126786Sjhb co->lg_provider = 442126786Sjhb geom_lookupid(gmp, 443126786Sjhb co->lg_provider)->lg_ptr; 444126748Sphk LIST_INSERT_HEAD( 445126786Sjhb &co->lg_provider->lg_consumers, 446126786Sjhb co, lg_consumers); 447126748Sphk } 448110603Sphk } 449110603Sphk } 450110603Sphk } 451110603Sphk return (0); 452110603Sphk} 453110603Sphk 454110603Sphkint 455110603Sphkgeom_gettree(struct gmesh *gmp) 456110603Sphk{ 457110603Sphk char *p; 458110603Sphk int error; 459110603Sphk 460110603Sphk p = geom_getxml(); 461146561Sphk if (p == NULL) 462146561Sphk return (errno); 463110603Sphk error = geom_xml2tree(gmp, p); 464110603Sphk free(p); 465110603Sphk return (error); 466110603Sphk} 467110603Sphk 468110603Sphkstatic void 469110603Sphkdelete_config(struct gconf *gp) 470110603Sphk{ 471110603Sphk struct gconfig *cf; 472110603Sphk 473110603Sphk for (;;) { 474110603Sphk cf = LIST_FIRST(gp); 475110603Sphk if (cf == NULL) 476110603Sphk return; 477126786Sjhb LIST_REMOVE(cf, lg_config); 478126786Sjhb free(cf->lg_name); 479126786Sjhb free(cf->lg_val); 480110603Sphk free(cf); 481110603Sphk } 482110603Sphk} 483110603Sphk 484110603Sphkvoid 485110603Sphkgeom_deletetree(struct gmesh *gmp) 486110603Sphk{ 487110603Sphk struct gclass *cl; 488110603Sphk struct ggeom *ge; 489110603Sphk struct gprovider *pr; 490110603Sphk struct gconsumer *co; 491110603Sphk 492126786Sjhb free(gmp->lg_ident); 493126786Sjhb gmp->lg_ident = NULL; 494110603Sphk for (;;) { 495126786Sjhb cl = LIST_FIRST(&gmp->lg_class); 496110603Sphk if (cl == NULL) 497110603Sphk break; 498126786Sjhb LIST_REMOVE(cl, lg_class); 499126786Sjhb delete_config(&cl->lg_config); 500126786Sjhb if (cl->lg_name) free(cl->lg_name); 501110603Sphk for (;;) { 502126786Sjhb ge = LIST_FIRST(&cl->lg_geom); 503110603Sphk if (ge == NULL) 504110603Sphk break; 505126786Sjhb LIST_REMOVE(ge, lg_geom); 506126786Sjhb delete_config(&ge->lg_config); 507126786Sjhb if (ge->lg_name) free(ge->lg_name); 508110603Sphk for (;;) { 509126786Sjhb pr = LIST_FIRST(&ge->lg_provider); 510110603Sphk if (pr == NULL) 511110603Sphk break; 512126786Sjhb LIST_REMOVE(pr, lg_provider); 513126786Sjhb delete_config(&pr->lg_config); 514126786Sjhb if (pr->lg_name) free(pr->lg_name); 515126786Sjhb if (pr->lg_mode) free(pr->lg_mode); 516110603Sphk free(pr); 517110603Sphk } 518110603Sphk for (;;) { 519126786Sjhb co = LIST_FIRST(&ge->lg_consumer); 520110603Sphk if (co == NULL) 521110603Sphk break; 522126786Sjhb LIST_REMOVE(co, lg_consumer); 523126786Sjhb delete_config(&co->lg_config); 524126786Sjhb if (co->lg_mode) free(co->lg_mode); 525110603Sphk free(co); 526110603Sphk } 527110603Sphk free(ge); 528110603Sphk } 529110603Sphk free(cl); 530110603Sphk } 531110603Sphk} 532