4578647 [rkeene@sledge /home/rkeene/devel/libconfig-0.2.5]$ cat -n conf_apache.c
  1 #include "compat.h"
  2 #include "libconfig.h"
  3 #include "libconfig_private.h"
  4 #include "conf_apache.h"
  5 
  6 #ifdef HAVE_CTYPE_H
  7 #include <ctype.h>
  8 #endif
  9 
 10 #ifdef HAVE_STDIO_H
 11 #include <stdio.h>
 12 #endif
 13 
 14 #ifdef HAVE_STRING_H
 15 #include <string.h>
 16 #endif
 17 
 18 #ifdef HAVE_SYS_TYPES_H
 19 #include <sys/types.h>
 20 #endif
 21 
 22 #ifdef HAVE_SYS_STAT_H
 23 #include <sys/stat.h>
 24 #endif
 25 
 26 #ifdef HAVE_UNISTD_H
 27 #include <unistd.h>
 28 #endif
 29 
 30 #ifdef HAVE_DIRENT_H
 31 #include <dirent.h>
 32 #endif
 33 
 34 static int lc_process_conf_apache_file(const char *configfile, const char *pathprefix);
 35 
 36 static int lc_process_conf_apache_include(const char *pathname, const char *pathprefix) {
 37     struct stat pathinfo;
 38     struct dirent *dinfo = NULL;
 39     char includepath[LC_LINEBUF_LEN] = {0};
 40     DIR *dh = NULL;
 41     int statret = -1, lcpcafret = -1;
 42     int retval = 0;
 43 
 44     statret = stat(pathname, &pathinfo);
 45     if (statret < 0) {
 46         return(-1);
 47     }
 48 
 49     if (S_ISDIR(pathinfo.st_mode)) {
 50         dh = opendir(pathname);
 51         if (dh == NULL) {
 52             return(-1);
 53         }
 54 
 55         while (1) {
 56             dinfo = readdir(dh);
 57             if (dinfo == NULL) {
 58                 break;
 59             }
 60 
 61             /* Skip files that begin with a dot ('.') */
 62             if (dinfo->d_name[0] == '.') continue;
 63 
 64             snprintf(includepath, sizeof(includepath) - 1, "%s/%s", pathname, dinfo->d_name);
 65             lcpcafret = lc_process_conf_apache_include(includepath, pathprefix);
 66             if (lcpcafret < 0) {
 67                 retval = -1;
 68                 /* XXX: should we break here (abort further including of files from a directory if one fails ?) */
 69                 break;
 70             }
 71         }
 72 
 73         closedir(dh);
 74     } else {
 75         lcpcafret = lc_process_conf_apache_file(pathname, pathprefix);
 76         if (lcpcafret < 0) {
 77             retval = -1;
 78         }
 79     }
 80 
 81     return(retval);
 82 }
 83 
 84 static int lc_process_conf_apache_file(const char *configfile, const char *pathprefix) {
 85     LC_FILE *configfp = NULL;
 86     const char *local_lc_errfile;
 87     char linebuf[LC_LINEBUF_LEN] = {0}, *linebuf_ptr = NULL, *tmp_ptr = NULL;
 88     char *lastsection = NULL;
 89     char qualifbuf[LC_LINEBUF_LEN] = {0};
 90     char *cmd = NULL, *value = NULL, *sep = NULL, *cmdend = NULL;
 91     char *fgetsret = NULL;
 92     int lcpvret = -1, lpcafret = -1;
 93     int invalid_section = 0, ignore_section = 0;
 94     int local_lc_errline;
 95     int retval = 0;
 96     lc_err_t save_lc_errno = LC_ERR_NONE;
 97 
 98     if (pathprefix != NULL) {
 99         /* Copy the prefix, if specified. */
100         strncpy(qualifbuf, pathprefix, sizeof(qualifbuf) - 1);
101     }
102 
103     local_lc_errfile = configfile;
104     local_lc_errline = 0;
105 
106     if (configfile == NULL) {
107         lc_errfile = local_lc_errfile;
108         lc_errline = local_lc_errline;
109         lc_errno = LC_ERR_INVDATA;
110         return(-1);
111     }
112 
113     configfp = lc_fopen(configfile, "r");
114 
115     if (configfp == NULL) {
116         lc_errfile = local_lc_errfile;
117         lc_errline = local_lc_errline;
118         lc_errno = LC_ERR_CANTOPEN;
119         return(-1);
120     }
121 
122     while (1) {
123         fgetsret = lc_fgets(linebuf, sizeof(linebuf) - 1, configfp);
124         if (fgetsret == NULL) {
125             break;
126         }
127         if (lc_feof(configfp)) {
128             break;
129         }
130 
131         local_lc_errline++;
132 
133         /* Remove trailing crap (but not spaces). */
134         linebuf_ptr = &linebuf[strlen(linebuf) - 1];
135         while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) {
136             *linebuf_ptr = '\0';
137             linebuf_ptr--;
138         }
139 
140         /* Remove leading spaces. */
141         linebuf_ptr = &linebuf[0];
142         while ((*linebuf_ptr == ' ' || *linebuf_ptr == '\t') && linebuf_ptr < (linebuf + sizeof(linebuf))) {
143             linebuf_ptr++;
144         }
145 
146         /* Handle section header. */
147         if (linebuf_ptr[0] == '<' && linebuf_ptr[strlen(linebuf_ptr) - 1] == '>' && linebuf_ptr < (linebuf +
	sizeof(linebuf))) {
148             /* Remove < and > from around the data. */
149             linebuf_ptr[strlen(linebuf_ptr) - 1] = '\0';
150             linebuf_ptr++;
151 
152             /* Lowercase the command part of the section. */
153             tmp_ptr = linebuf_ptr;
154             while (*tmp_ptr != '\0' && *tmp_ptr != ' ' && tmp_ptr < (linebuf + sizeof(linebuf))) {
155                 *tmp_ptr = tolower(*tmp_ptr);
156                 tmp_ptr++;
157             }
158 
159             /* If this is a close section command, handle it */
160             if (linebuf_ptr[0] == '/') {
161                 linebuf_ptr++;
162                 cmd = linebuf_ptr; 
163 
164                 /* Find the last section closed. */
165                 tmp_ptr = strrchr(qualifbuf, '.');
166                 if (tmp_ptr == NULL) {
167                     lastsection = qualifbuf;
168                     tmp_ptr = qualifbuf;
169                 } else {
170                     lastsection = tmp_ptr + 1;
171                 }
172 
173                 if (strcmp(cmd, lastsection) != 0) {
174 #ifdef DEBUG
175                     fprintf(stderr, "Section closing does not match last opened section.\n");
176                     fprintf(stderr, "Last opened = \"%s\", Closing = \"%s\"\n", lastsection, cmd);
177 #endif
178                     retval = -1;
179                     lc_errfile = local_lc_errfile;
180                     lc_errline = local_lc_errline;
181                     lc_errno = LC_ERR_BADFORMAT;
182 
183                     /* For this error, we abort immediately. */
184                     break;
185                 }
186 
187                 lcpvret = lc_process_var(qualifbuf, NULL, NULL, LC_FLAGS_SECTIONEND);
188                 if (lcpvret < 0) {
189 #ifdef DEBUG
190                     fprintf(stderr, "Invalid section terminating: \"%s\"\n", qualifbuf);
191 #endif
192                 }
193 
194                 /* Remove the "lastsection" part.. */
195                 *tmp_ptr = '\0';
196 
197                 /* We just sucessfully closed the last section opened,
198                    we must be in a valid section now since we only open
199                    sections from within valid sections. */
200                 invalid_section = 0;
201                 ignore_section = 0;
202 
203                 continue;
204             }
205             /* Otherwise, open a new section. */
206 
207             /* Don't open a section from an invalid section. */
208             if (invalid_section == 1 || ignore_section == 1) {
209                 continue;
210             }
211 
212             /* Parse out any argument passed. */
213             sep = strpbrk(linebuf_ptr, " \t");
214 
215             if (sep != NULL) {
216                 cmdend = sep;
217                 /* Delete space at the end of the command. */
218                 cmdend--; /* It currently derefs to the seperator.. */
219                 while (*cmdend <= ' ') {
220                     *cmdend = '\0';
221                     cmdend--;
222                 }
223 
224                 /* Delete the seperator char and any leading space. */
225                 *sep = '\0';
226                 sep++;
227                 while (*sep == ' ' || *sep == '\t') {
228                     sep++;
229                 }
230                 value = sep;
231             } else {
232                 /* XXX: should this be "" or NULL ? */
233                 value = "";
234             }
235 
236             cmd = linebuf_ptr;
237 
238             if (qualifbuf[0] != '\0') {
239                 strncat(qualifbuf, ".", sizeof(qualifbuf) - strlen(qualifbuf) - 1);
240             }
241             strncat(qualifbuf, cmd, sizeof(qualifbuf) - strlen(qualifbuf) - 1);
242 
243             lcpvret = lc_process_var(qualifbuf, value, NULL, LC_FLAGS_SECTIONSTART);
244             if (lcpvret < 0) {
245 #ifdef DEBUG
246                 fprintf(stderr, "Invalid section: \"%s\"\n", qualifbuf);
247 #endif
248                 invalid_section = 1;
249                 lc_errfile = local_lc_errfile;
250                 lc_errline = local_lc_errline;
251                 lc_errno = LC_ERR_INVSECTION;
252                 retval = -1;
253             }
254             if (lcpvret == LC_CBRET_IGNORESECTION) {
255                 ignore_section = 1;
256             }
257             continue;
258         }
259 
260         /* Drop comments and blank lines. */
261         if (*linebuf_ptr == '#' || *linebuf_ptr == '\0') {
262             continue;
263         }
264 
265         /* Don't handle things for a section that doesn't exist. */
266         if (invalid_section == 1) {
267 #ifdef DEBUG
268             fprintf(stderr, "Ignoring line (because invalid section): %s\n", linebuf);
269 #endif
270             continue;
271         }
272         if (ignore_section == 1) {
273 #ifdef DEBUG
274             fprintf(stderr, "Ignoring line (because ignored section): %s\n", linebuf);
275 #endif
276             continue;
277         }
278 
279         /* Find the command and the data in the line. */
280         sep = strpbrk(linebuf_ptr, " \t");
281         if (sep != NULL) {
282             cmdend = sep;
283 
284             /* Delete space at the end of the command. */
285             cmdend--; /* It currently derefs to the seperator.. */
286             while (*cmdend <= ' ' && cmdend >= sep) {
287                 *cmdend = '\0';
288                 cmdend--;
289             }
290 
291             /* Delete the seperator char and any leading space. */
292             *sep = '\0';
293             sep++;
294             while (*sep == ' ' || *sep == '\t') {
295                 sep++;
296             }
297             value = sep;
298         } else {
299             value = NULL;
300         }
301 
302         cmd = linebuf_ptr;
303 
304         /* Handle special commands. */
305         if (strcasecmp(cmd, "include") == 0) {
306             if (value == NULL) {
307                 lc_errfile = local_lc_errfile;
308                 lc_errline = local_lc_errline;
309                 lc_errno = LC_ERR_BADFORMAT;
310                 retval = -1;
311 #ifdef DEBUG
312                 fprintf(stderr, "Invalid include command.\n");
313 #endif
314                 continue;
315             }
316 
317             lpcafret = lc_process_conf_apache_include(value, qualifbuf);
318             if (lpcafret < 0) {
319 #ifdef DEBUG
320                 fprintf(stderr, "Error in included file.\n");
321 #endif
322                 retval = -1;
323             }
324             continue;
325         }
326 
327         /* Create the fully qualified variable name. */
328         if (qualifbuf[0] != '\0') {
329             strncat(qualifbuf, ".", sizeof(qualifbuf) - strlen(qualifbuf) - 1);
330         }
331         strncat(qualifbuf, cmd, sizeof(qualifbuf) - strlen(qualifbuf) - 1);
332 
333         /* Call the parent and tell them we have data. */
334         save_lc_errno = lc_errno;
335         lc_errno = LC_ERR_NONE;
336         lcpvret = lc_process_var(qualifbuf, NULL, value, LC_FLAGS_VAR);
337         if (lcpvret < 0) {
338             if (lc_errno == LC_ERR_NONE) {
339 #ifdef DEBUG
340                 fprintf(stderr, "Invalid command: \"%s\"\n", cmd);
341 #endif
342                 lc_errfile = local_lc_errfile;
343                 lc_errline = local_lc_errline;
344                 lc_errno = LC_ERR_INVCMD;
345             } else {
346 #ifdef DEBUG
347                 fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n");
348 #endif
349             }
350             lc_errfile = local_lc_errfile;
351             lc_errline = local_lc_errline;
352             retval = -1;
353             break;
354         } else {
355             lc_errno = save_lc_errno;
356         }
357 
358         /* Remove the "cmd" part of the buffer. */
359         tmp_ptr = strrchr(qualifbuf, '.');
360         if (tmp_ptr == NULL) {
361             tmp_ptr = qualifbuf;
362         }
363         *tmp_ptr = '\0';
364     }
365 
366     lc_fclose(configfp);
367 
368     return(retval);
369 }
370 
371 int lc_process_conf_apache(const char *appname, const char *configfile) {
372     return(lc_process_conf_apache_file(configfile, NULL));
373 }
4578648 [rkeene@sledge /home/rkeene/devel/libconfig-0.2.5]$

Click here to go back to the directory listing.
Click here to download this file.
last modified: 2006-12-16 05:33:15