Home | History | Annotate | Download | only in avahi-daemon
      1 /***
      2   This file is part of avahi.
      3 
      4   avahi is free software; you can redistribute it and/or modify it
      5   under the terms of the GNU Lesser General Public License as
      6   published by the Free Software Foundation; either version 2.1 of the
      7   License, or (at your option) any later version.
      8 
      9   avahi is distributed in the hope that it will be useful, but WITHOUT
     10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     11   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
     12   Public License for more details.
     13 
     14   You should have received a copy of the GNU Lesser General Public
     15   License along with avahi; if not, write to the Free Software
     16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
     17   USA.
     18 ***/
     19 
     20 #ifdef HAVE_CONFIG_H
     21 #include <config.h>
     22 #endif
     23 
     24 #include <stdio.h>
     25 #include <string.h>
     26 #include <errno.h>
     27 #include <ctype.h>
     28 
     29 #include "avahi-common/avahi-malloc.h"
     30 #include <avahi-core/log.h>
     31 
     32 #include "ini-file-parser.h"
     33 
     34 AvahiIniFile* avahi_ini_file_load(const char *fname) {
     35     AvahiIniFile *f;
     36     FILE *fo;
     37     AvahiIniFileGroup *group = NULL;
     38     unsigned line;
     39 
     40     assert(fname);
     41 
     42     if (!(fo = fopen(fname, "r"))) {
     43         avahi_log_error("Failed to open file '%s': %s", fname, strerror(errno));
     44         return NULL;
     45     }
     46 
     47     f = avahi_new(AvahiIniFile, 1);
     48     AVAHI_LLIST_HEAD_INIT(AvahiIniFileGroup, f->groups);
     49     f->n_groups = 0;
     50 
     51     line = 0;
     52     while (!feof(fo)) {
     53         char ln[256], *s, *e;
     54         AvahiIniFilePair *pair;
     55 
     56         if (!(fgets(ln, sizeof(ln), fo)))
     57             break;
     58 
     59         line++;
     60 
     61         s = ln + strspn(ln, " \t");
     62         s[strcspn(s, "\r\n")] = 0;
     63 
     64         /* Skip comments and empty lines */
     65         if (*s == '#' || *s == '%' || *s == 0)
     66             continue;
     67 
     68         if (*s == '[') {
     69             /* new group */
     70 
     71             if (!(e = strchr(s, ']'))) {
     72                 avahi_log_error("Unclosed group header in %s:%u: <%s>", fname, line, s);
     73                 goto fail;
     74             }
     75 
     76             *e = 0;
     77 
     78             group = avahi_new(AvahiIniFileGroup, 1);
     79             group->name = avahi_strdup(s+1);
     80             group->n_pairs = 0;
     81             AVAHI_LLIST_HEAD_INIT(AvahiIniFilePair, group->pairs);
     82 
     83             AVAHI_LLIST_PREPEND(AvahiIniFileGroup, groups, f->groups, group);
     84             f->n_groups++;
     85         } else {
     86 
     87             /* Normal assignment */
     88             if (!(e = strchr(s, '='))) {
     89                 avahi_log_error("Missing assignment in %s:%u: <%s>", fname, line, s);
     90                 goto fail;
     91             }
     92 
     93             if (!group) {
     94                 avahi_log_error("Assignment outside group in %s:%u <%s>", fname, line, s);
     95                 goto fail;
     96             }
     97 
     98             /* Split the key and the value */
     99             *(e++) = 0;
    100 
    101             pair = avahi_new(AvahiIniFilePair, 1);
    102             pair->key = avahi_strdup(s);
    103             pair->value = avahi_strdup(e);
    104 
    105             AVAHI_LLIST_PREPEND(AvahiIniFilePair, pairs, group->pairs, pair);
    106             group->n_pairs++;
    107         }
    108     }
    109 
    110     fclose(fo);
    111 
    112     return f;
    113 
    114 fail:
    115 
    116     if (fo)
    117         fclose(fo);
    118 
    119     if (f)
    120         avahi_ini_file_free(f);
    121 
    122     return NULL;
    123 }
    124 
    125 void avahi_ini_file_free(AvahiIniFile *f) {
    126     AvahiIniFileGroup *g;
    127     assert(f);
    128 
    129     while ((g = f->groups)) {
    130         AvahiIniFilePair *p;
    131 
    132         while ((p = g->pairs)) {
    133             avahi_free(p->key);
    134             avahi_free(p->value);
    135 
    136             AVAHI_LLIST_REMOVE(AvahiIniFilePair, pairs, g->pairs, p);
    137             avahi_free(p);
    138         }
    139 
    140         avahi_free(g->name);
    141 
    142         AVAHI_LLIST_REMOVE(AvahiIniFileGroup, groups, f->groups, g);
    143         avahi_free(g);
    144     }
    145 
    146     avahi_free(f);
    147 }
    148 
    149 char** avahi_split_csv(const char *t) {
    150     unsigned n_comma = 0;
    151     const char *p;
    152     char **r, **i;
    153 
    154     for (p = t; *p; p++)
    155         if (*p == ',')
    156             n_comma++;
    157 
    158     i = r = avahi_new(char*, n_comma+2);
    159 
    160     for (;;) {
    161         size_t n, l = strcspn(t, ",");
    162         const char *c;
    163 
    164         /* Ignore leading blanks */
    165         for (c = t, n = l; isblank(*c); c++, n--);
    166 
    167         /* Ignore trailing blanks */
    168         for (; n > 0 && isblank(c[n-1]); n--);
    169 
    170         *(i++) = avahi_strndup(c, n);
    171 
    172         t += l;
    173 
    174         if (*t == 0)
    175             break;
    176 
    177         assert(*t == ',');
    178         t++;
    179     }
    180 
    181     *i = NULL;
    182 
    183     return r;
    184 }
    185 
    186 void avahi_strfreev(char **p) {
    187     char **i;
    188 
    189     if (!p)
    190         return;
    191 
    192     for (i = p; *i; i++)
    193         avahi_free(*i);
    194 
    195     avahi_free(p);
    196 }
    197