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