/* $Id$ */ /*** This file is part of avahi. avahi is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. avahi 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with avahi; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***/ #include #include #include #include #include #include #include "ini-file-parser.h" AvahiIniFile* avahi_ini_file_load(const char *fname) { AvahiIniFile *f; FILE *fo; AvahiIniFileGroup *group = NULL; unsigned line; assert(fname); if (!(fo = fopen(fname, "r"))) { avahi_log_error("Failed to open file '%s': %s", fname, strerror(errno)); return NULL; } f = avahi_new(AvahiIniFile, 1); AVAHI_LLIST_HEAD_INIT(AvahiIniFileGroup, f->groups); f->n_groups = 0; line = 0; while (!feof(fo)) { char ln[256], *s, *e; AvahiIniFilePair *pair; if (!(fgets(ln, sizeof(ln), fo))) break; line++; s = ln + strspn(ln, " \t"); s[strcspn(s, "\r\n")] = 0; /* Skip comments and empty lines */ if (*s == '#' || *s == '%' || *s == 0) continue; if (*s == '[') { /* new group */ if (!(e = strchr(s, ']'))) { avahi_log_error("Unclosed group header in %s:%u: <%s>", fname, line, s); goto fail; } *e = 0; group = avahi_new(AvahiIniFileGroup, 1); group->name = avahi_strdup(s+1); group->n_pairs = 0; AVAHI_LLIST_HEAD_INIT(AvahiIniFilePair, group->pairs); AVAHI_LLIST_PREPEND(AvahiIniFileGroup, groups, f->groups, group); f->n_groups++; } else { /* Normal assignment */ if (!(e = strchr(s, '='))) { avahi_log_error("Missing assignment in %s:%u: <%s>", fname, line, s); goto fail; } if (!group) { avahi_log_error("Assignment outside group in %s:%u <%s>", fname, line, s); goto fail; } /* Split the key and the value */ *(e++) = 0; pair = avahi_new(AvahiIniFilePair, 1); pair->key = avahi_strdup(s); pair->value = avahi_strdup(e); AVAHI_LLIST_PREPEND(AvahiIniFilePair, pairs, group->pairs, pair); group->n_pairs++; } } fclose(fo); return f; fail: if (fo) fclose(fo); if (f) avahi_ini_file_free(f); return NULL; } void avahi_ini_file_free(AvahiIniFile *f) { AvahiIniFileGroup *g; assert(f); while ((g = f->groups)) { AvahiIniFilePair *p; while ((p = g->pairs)) { avahi_free(p->key); avahi_free(p->value); AVAHI_LLIST_REMOVE(AvahiIniFilePair, pairs, g->pairs, p); avahi_free(p); } avahi_free(g->name); AVAHI_LLIST_REMOVE(AvahiIniFileGroup, groups, f->groups, g); avahi_free(g); } avahi_free(f); } char** avahi_split_csv(const char *t) { unsigned n_comma = 0; const char *p; char **r, **i; for (p = t; *p; p++) if (*p == ',') n_comma++; i = r = avahi_new(char*, n_comma+2); for (;;) { size_t n, l = strcspn(t, ","); const char *c; /* Ignore leading blanks */ for (c = t, n = l; isblank(*c); c++, n--); /* Ignore trailing blanks */ for (; n > 0 && isblank(c[n-1]); n--); *(i++) = avahi_strndup(c, n); t += l; if (*t == 0) break; assert(*t == ','); t++; } *i = NULL; return r; } void avahi_strfreev(char **p) { char **i; if (!p) return; for (i = p; *i; i++) avahi_free(*i); avahi_free(p); }