root/cherokee/trunk/cherokee/config_reader.c

Revision 1726, 5.3 kB (checked in by alo, 2 months ago)

--

Line 
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* Cherokee
4  *
5  * Authors:
6  *      Alvaro Lopez Ortega <alvaro@alobbs.com>
7  *
8  * Copyright (C) 2001-2008 Alvaro Lopez Ortega
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of version 2 of the GNU General Public
12  * License as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22  * USA
23  */
24
25 #include "common-internal.h"
26 #include "config_reader.h"
27 #include "util.h"
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 #define ENTRIES "config"
34
35
36 static ret_t
37 do_parse_file (cherokee_config_node_t *conf, const char *file)
38 {
39         ret_t              ret;
40         cherokee_buffer_t  buf = CHEROKEE_BUF_INIT;
41
42         ret = cherokee_buffer_read_file (&buf, (char *)file);
43         if (ret != ret_ok) return ret;
44
45         ret = cherokee_config_reader_parse_string (conf, &buf);
46         if (ret != ret_ok) goto error;
47
48         cherokee_buffer_mrproper (&buf);
49         return ret_ok;
50
51 error:
52         cherokee_buffer_mrproper (&buf);
53         return ret_error;
54 }
55
56
57 static ret_t
58 do_include (cherokee_config_node_t *conf, cherokee_buffer_t *path)
59 {
60         int         re;
61         struct stat info;
62
63         re = stat (path->buf, &info);
64         if (re < 0) {
65                 PRINT_MSG ("Could not access '%s'\n", path->buf);
66                 return ret_error;
67         }
68
69         if (S_ISREG(info.st_mode)) {
70                 return do_parse_file (conf, path->buf);
71
72         } else if (S_ISDIR(info.st_mode)) {
73                 DIR              *dir;
74                 struct dirent    *entry;
75                 int               entry_len;
76                
77                 dir = opendir (path->buf);
78                 if (dir == NULL) return ret_error;
79                
80                 while ((entry = readdir(dir)) != NULL) {
81                         ret_t             ret;
82                         cherokee_buffer_t full_new = CHEROKEE_BUF_INIT;
83                        
84                         /* Ignore backup files
85                          */
86                         entry_len = strlen(entry->d_name);
87                        
88                         if ((entry->d_name[0] == '.') ||
89                             (entry->d_name[0] == '#') ||
90                             (entry->d_name[entry_len-1] == '~'))
91                         {
92                                 continue;
93                         }
94                        
95                         ret = cherokee_buffer_add_va (&full_new, "%s/%s", path->buf, entry->d_name);
96                         if (unlikely (ret != ret_ok)) return ret;
97
98                         ret = do_parse_file (conf, full_new.buf);
99                         if (ret != ret_ok) {
100                                 cherokee_buffer_mrproper (&full_new);
101                                 return ret;
102                         }
103
104                         cherokee_buffer_mrproper (&full_new);
105                 }
106                        
107                 closedir (dir);
108                 return ret_ok;
109         }
110        
111         SHOULDNT_HAPPEN;
112         return ret_error;
113 }
114
115
116 static ret_t
117 check_config_node_sanity (cherokee_config_node_t *conf)
118 {
119         cherokee_list_t *i, *j;
120         int              re;
121
122         /* Finds duplicate properties written in lower/upper-case
123          */
124         cherokee_config_node_foreach (i, conf)
125         {
126                 cherokee_config_node_foreach (j, conf)
127                 {
128                         if (i == j)
129                                 continue;
130
131                         re = cherokee_buffer_case_cmp_buf (&CONFIG_NODE(i)->key,
132                                                            &CONFIG_NODE(j)->key);
133                         if (re == 0) {
134                                 PRINT_ERROR ("ERROR: '%s' and '%s' as child of the same node.\n",
135                                              CONFIG_NODE(i)->key.buf, CONFIG_NODE(j)->key.buf);
136                                 return ret_error;
137                         }
138                 }
139         }
140
141         return ret_ok;
142 }
143
144
145 ret_t
146 cherokee_config_reader_parse_string (cherokee_config_node_t *conf, cherokee_buffer_t *buf)
147 {
148         ret_t              ret;
149         char              *eol;
150         char              *begin;
151         char              *equal;
152         char              *tmp;
153         char              *eof;
154         cherokee_buffer_t  key = CHEROKEE_BUF_INIT;
155         cherokee_buffer_t  val = CHEROKEE_BUF_INIT;
156
157         eof = buf->buf + buf->len;
158
159         begin = buf->buf;
160         do {
161                 /* Skip whites at the begining
162                  */
163                 while ((begin < eof) &&
164                        ((*begin == ' ') || (*begin == '\t') ||
165                         (*begin == '\r') || (*begin == '\n')))
166                 {
167                         begin++;
168                 }
169
170                 /* Look for the EOL
171                  */
172                 eol = cherokee_min_str (strchr(begin, '\n'),
173                                         strchr(begin, '\r'));
174
175                 if (eol == NULL)
176                         break;
177
178                 /* Check that it's long enough
179                  */
180                 if (eol - begin <= 4) {
181                         begin = eol + 1;
182                         continue;
183                 }
184                 *eol = '\0';
185
186                 /* Read the line
187                  */
188                 if (*begin != '#') {
189                         cuint_t val_len;
190
191                         equal = strstr (begin, " = ");
192                         if (equal == NULL) goto error;
193                
194                         tmp = equal;
195
196                         /* Skip whites: end of the key
197                          */
198                         while (*tmp == ' ')
199                                 tmp--;
200                         cherokee_buffer_add (&key, begin, (tmp + 1) - begin);
201                        
202                         tmp = equal + 3;
203                         while (*tmp == ' ')
204                                 tmp++;
205
206                         /* Skip whites: end of the value
207                          */
208                         val_len = strlen(tmp);
209                         while ((val_len >= 1) &&
210                                (tmp[val_len-1] == ' '))
211                         {
212                                 val_len--;
213                         }
214
215                         cherokee_buffer_add (&val, tmp, val_len);
216                        
217                         TRACE(ENTRIES, "'%s' => '%s'\n", key.buf, val.buf);
218                        
219                         ret = cherokee_config_node_add_buf (conf, &key, &val);
220                         if (ret != ret_ok)
221                                 goto error;
222                 }
223
224                 /* Next loop
225                  */
226                 begin = eol + 1;
227
228                 cherokee_buffer_clean (&key);
229                 cherokee_buffer_clean (&val);
230
231         } while (eol != NULL);
232        
233         cherokee_buffer_mrproper (&key);
234         cherokee_buffer_mrproper (&val);
235
236         /* Sanity check
237          */
238         ret = check_config_node_sanity (conf);
239         if (ret != ret_ok)
240                 return ret;
241        
242         return ret_ok;
243
244 error:
245         PRINT_MSG ("Error parsing: %s\n", begin);
246
247         cherokee_buffer_mrproper (&key);
248         cherokee_buffer_mrproper (&val);
249         return ret_error;
250 }
251
252
253 ret_t
254 cherokee_config_reader_parse (cherokee_config_node_t *conf, cherokee_buffer_t *path)
255 {
256         return do_include (conf, path);
257 }
Note: See TracBrowser for help on using the browser.