3 #include "libconfig_private.h"
4 #include "conf_apache.h"
18 #ifdef HAVE_SYS_TYPES_H
19 #include <sys/types.h>
22 #ifdef HAVE_SYS_STAT_H
34 static int lc_process_conf_apache_file(const char *configfile, const char *pathprefix);
36 static int lc_process_conf_apache_include(const char *pathname, const char *pathprefix) {
38 struct dirent *dinfo = NULL;
39 char includepath[LC_LINEBUF_LEN] = {0};
41 int statret = -1, lcpcafret = -1;
44 statret = stat(pathname, &pathinfo);
49 if (S_ISDIR(pathinfo.st_mode)) {
50 dh = opendir(pathname);
61 /* Skip files that begin with a dot ('.') */
62 if (dinfo->d_name[0] == '.') continue;
64 snprintf(includepath, sizeof(includepath) - 1, "%s/%s", pathname, dinfo->d_name);
65 lcpcafret = lc_process_conf_apache_include(includepath, pathprefix);
68 /* XXX: should we break here (abort further including of files from a directory if one fails ?) */
74 lcpcafret = lc_process_conf_apache_file(pathname, pathprefix);
83 static int lc_process_conf_apache_file(const char *configfile, const char *pathprefix) {
84 LC_FILE *configfp = NULL;
85 const char *local_lc_errfile;
86 char linebuf[LC_LINEBUF_LEN] = {0}, *linebuf_ptr = NULL, *tmp_ptr = NULL;
87 char *lastsection = NULL;
88 char qualifbuf[LC_LINEBUF_LEN] = {0};
89 char *cmd = NULL, *value = NULL, *sep = NULL, *cmdend = NULL;
90 char *fgetsret = NULL;
91 int lcpvret = -1, lpcafret = -1;
92 int invalid_section = 0, ignore_section = 0;
95 lc_err_t save_lc_errno = LC_ERR_NONE;
97 if (pathprefix != NULL) {
98 /* Copy the prefix, if specified. */
99 strncpy(qualifbuf, pathprefix, sizeof(qualifbuf) - 1);
102 local_lc_errfile = configfile;
103 local_lc_errline = 0;
105 if (configfile == NULL) {
106 lc_errfile = local_lc_errfile;
107 lc_errline = local_lc_errline;
108 lc_errno = LC_ERR_INVDATA;
112 configfp = lc_fopen(configfile, "r");
114 if (configfp == NULL) {
115 lc_errfile = local_lc_errfile;
116 lc_errline = local_lc_errline;
117 lc_errno = LC_ERR_CANTOPEN;
122 fgetsret = lc_fgets(linebuf, sizeof(linebuf) - 1, configfp);
123 if (fgetsret == NULL) {
126 if (lc_feof(configfp)) {
132 /* Remove trailing crap (but not spaces). */
133 linebuf_ptr = &linebuf[strlen(linebuf) - 1];
134 while (*linebuf_ptr < ' ' && linebuf_ptr >= linebuf) {
139 /* Remove leading spaces. */
140 linebuf_ptr = &linebuf[0];
141 while (*linebuf_ptr == ' ' || *linebuf_ptr == '\t') {
145 /* Handle section header. */
146 if (linebuf_ptr[0] == '<' && linebuf_ptr[strlen(linebuf_ptr) - 1] == '>') {
147 /* Remove < and > from around the data. */
148 linebuf_ptr[strlen(linebuf_ptr) - 1] = '\0';
151 /* Lowercase the command part of the section. */
152 tmp_ptr = linebuf_ptr;
153 while (*tmp_ptr != '\0' && *tmp_ptr != ' ') {
154 *tmp_ptr = tolower(*tmp_ptr);
158 /* If this is a close section command, handle it */
159 if (linebuf_ptr[0] == '/') {
163 /* Find the last section closed. */
164 tmp_ptr = strrchr(qualifbuf, '.');
165 if (tmp_ptr == NULL) {
166 lastsection = qualifbuf;
169 lastsection = tmp_ptr + 1;
172 if (strcmp(cmd, lastsection) != 0) {
174 fprintf(stderr, "Section closing does not match last opened section.\n");
175 fprintf(stderr, "Last opened = \"%s\", Closing = \"%s\"\n", lastsection, cmd);
178 lc_errfile = local_lc_errfile;
179 lc_errline = local_lc_errline;
180 lc_errno = LC_ERR_BADFORMAT;
182 /* For this error, we abort immediately. */
186 lcpvret = lc_process_var(qualifbuf, NULL, NULL, LC_FLAGS_SECTIONEND);
189 fprintf(stderr, "Invalid section terminating: \"%s\"\n", qualifbuf);
193 /* Remove the "lastsection" part.. */
196 /* We just sucessfully closed the last section opened,
197 we must be in a valid section now since we only open
198 sections from within valid sections. */
204 /* Otherwise, open a new section. */
206 /* Don't open a section from an invalid section. */
207 if (invalid_section == 1 || ignore_section == 1) {
211 /* Parse out any argument passed. */
212 sep = strpbrk(linebuf_ptr, " \t");
216 /* Delete space at the end of the command. */
217 cmdend--; /* It currently derefs to the seperator.. */
218 while (*cmdend <= ' ') {
223 /* Delete the seperator char and any leading space. */
226 while (*sep == ' ' || *sep == '\t') {
231 /* XXX: should this be "" or NULL ? */
237 if (qualifbuf[0] != '\0') {
238 strncat(qualifbuf, ".", sizeof(qualifbuf) - strlen(qualifbuf) - 1);
240 strncat(qualifbuf, cmd, sizeof(qualifbuf) - strlen(qualifbuf) - 1);
242 lcpvret = lc_process_var(qualifbuf, value, NULL, LC_FLAGS_SECTIONSTART);
245 fprintf(stderr, "Invalid section: \"%s\"\n", qualifbuf);
248 lc_errfile = local_lc_errfile;
249 lc_errline = local_lc_errline;
250 lc_errno = LC_ERR_INVSECTION;
253 if (lcpvret == LC_CBRET_IGNORESECTION) {
259 /* Drop comments and blank lines. */
260 if (*linebuf_ptr == '#' || *linebuf_ptr == '\0') {
264 /* Don't handle things for a section that doesn't exist. */
265 if (invalid_section == 1) {
267 fprintf(stderr, "Ignoring line (because invalid section): %s\n", linebuf);
271 if (ignore_section == 1) {
273 fprintf(stderr, "Ignoring line (because ignored section): %s\n", linebuf);
278 /* Find the command and the data in the line. */
279 sep = strpbrk(linebuf_ptr, " \t");
283 /* Delete space at the end of the command. */
284 cmdend--; /* It currently derefs to the seperator.. */
285 while (*cmdend <= ' ') {
290 /* Delete the seperator char and any leading space. */
293 while (*sep == ' ' || *sep == '\t') {
303 /* Handle special commands. */
304 if (strcasecmp(cmd, "include") == 0) {
306 lc_errfile = local_lc_errfile;
307 lc_errline = local_lc_errline;
308 lc_errno = LC_ERR_BADFORMAT;
311 fprintf(stderr, "Invalid include command.\n");
316 lpcafret = lc_process_conf_apache_include(value, qualifbuf);
319 fprintf(stderr, "Error in included file.\n");
326 /* Create the fully qualified variable name. */
327 if (qualifbuf[0] != '\0') {
328 strncat(qualifbuf, ".", sizeof(qualifbuf) - strlen(qualifbuf) - 1);
330 strncat(qualifbuf, cmd, sizeof(qualifbuf) - strlen(qualifbuf) - 1);
332 /* Call the parent and tell them we have data. */
333 save_lc_errno = lc_errno;
334 lc_errno = LC_ERR_NONE;
335 lcpvret = lc_process_var(qualifbuf, NULL, value, LC_FLAGS_VAR);
337 if (lc_errno == LC_ERR_NONE) {
339 fprintf(stderr, "Invalid command: \"%s\"\n", cmd);
341 lc_errfile = local_lc_errfile;
342 lc_errline = local_lc_errline;
343 lc_errno = LC_ERR_INVCMD;
346 fprintf(stderr, "Error processing command (command was valid, but an error occured, errno was set)\n");
349 lc_errfile = local_lc_errfile;
350 lc_errline = local_lc_errline;
353 lc_errno = save_lc_errno;
356 /* Remove the "cmd" part of the buffer. */
357 tmp_ptr = strrchr(qualifbuf, '.');
358 if (tmp_ptr == NULL) {
369 int lc_process_conf_apache(const char *appname, const char *configfile) {
370 return(lc_process_conf_apache_file(configfile, NULL));