aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-09-04 19:27:57 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-09-04 19:27:57 +0000
commitc763cea500c5782fba9178af81a07edfebfa2dea (patch)
tree8f570ead324649fe0c9c3c64ad10ed5d2a61ac2a
parentf270347bfbc5bf5600b634c424b1530fa2af040c (diff)
downloadgsc-c763cea500c5782fba9178af81a07edfebfa2dea.tar.gz
gsc-c763cea500c5782fba9178af81a07edfebfa2dea.tar.bz2
* configure.ac, Makefile.am: Remove wydawca
* lib/cfg.c (find_cfg_fun): Implement default handler (read_cont_line): Fix reading lines that not terminate with a newline. (gsc_config_parse): Initialize new gsc_config_file_t fields * lib/gsc.h (gsc_config_file_t): New fields dev, ino, prev and kwtab. (cfg_include_handler, cfg_include_start, cfg_include_stop): new functions. * lib/cfgincl.c: New file. Implementation of include feature in configuration files. * lib/Makefile.am: Add cfgincl.c git-svn-id: file:///svnroot/gsc/trunk@305 d2de0444-eb31-0410-8365-af798a554d48
-rw-r--r--ChangeLog15
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac6
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/cfg.c23
-rw-r--r--lib/cfgincl.c109
-rw-r--r--lib/gsc.h13
7 files changed, 159 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 544cd63..e3e4f0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2007-09-04 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * configure.ac, Makefile.am: Remove wydawca
+ * lib/cfg.c (find_cfg_fun): Implement default handler
+ (read_cont_line): Fix reading lines that not terminate with a
+ newline.
+ (gsc_config_parse): Initialize new gsc_config_file_t fields
+ * lib/gsc.h (gsc_config_file_t): New fields dev, ino, prev and
+ kwtab.
+ (cfg_include_handler, cfg_include_start, cfg_include_stop): new
+ functions.
+ * lib/cfgincl.c: New file. Implementation of include feature in
+ configuration files.
+ * lib/Makefile.am: Add cfgincl.c
+
2007-09-01 Sergey Poznyakoff <gray@gnu.org.ua>
Wydawca moved to a separate project
diff --git a/Makefile.am b/Makefile.am
index ef037d7..6215e1f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,5 +35,4 @@ SUBDIRS=\
mc\
ppp\
rc.d\
- jabberd\
- wydawca
+ jabberd
diff --git a/configure.ac b/configure.ac
index 516dbba..97a928d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -117,8 +117,7 @@ maint
mc
ppp
rc.d
-jabberd
-wydawca'
+jabberd'
AC_ARG_VAR([XMODLIST],
[Comma-delimited list of modules to exclude from building (see also --enable-modules)])
@@ -190,7 +189,6 @@ AC_CONFIG_FILES([Makefile
mc/Makefile
ppp/Makefile
rc.d/Makefile
- jabberd/Makefile
- wydawca/Makefile])
+ jabberd/Makefile])
AC_OUTPUT
diff --git a/lib/Makefile.am b/lib/Makefile.am
index bd00dd7..7765604 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2,6 +2,7 @@ noinst_LIBRARIES=libgsc.a
libgsc_a_SOURCES = \
argcv.c\
cfg.c\
+ cfgincl.c\
interval.c\
syslog.c\
userprivs.c\
diff --git a/lib/cfg.c b/lib/cfg.c
index a45828b..354568d 100644
--- a/lib/cfg.c
+++ b/lib/cfg.c
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
@@ -34,8 +35,8 @@ find_cfg_fun (struct gsc_config_keyword *kwtab, char *kw)
{
for (; kwtab->kw; kwtab++)
if (strcmp (kwtab->kw, kw) == 0)
- return kwtab->handler;
- return NULL;
+ break;
+ return kwtab->handler;
}
ssize_t
@@ -49,6 +50,9 @@ read_cont_line (gsc_config_file_t *file)
if (len <= 0)
return len;
+ if (file->buf[len-1] != '\n')
+ return len;
+
file->buf[--len] = 0;
if (len > 0 && file->buf[len-1] == '\\')
{
@@ -63,7 +67,8 @@ read_cont_line (gsc_config_file_t *file)
break;
file->line++;
- file->buf[--rc] = 0;
+ if (file->buf[rc-1] == '\n')
+ file->buf[--rc] = 0;
newbuf[--len] = 0;
len += rc;
if (len + 1 > newsize)
@@ -124,7 +129,10 @@ gsc_config_parse_block (gsc_config_file_t *file, void *data,
fun = find_cfg_fun (kwtab, kw);
if (fun)
- fun (file, kw, val, data);
+ {
+ file->kwtab = kwtab;
+ fun (file, kw, val, data);
+ }
else
file->error_msg (file->file_name, file->line, "unrecognized line");
}
@@ -148,6 +156,10 @@ gsc_config_parse (const char *config_file,
struct gsc_config_keyword *kwh)
{
gsc_config_file_t file;
+ struct stat st;
+
+ if (stat (config_file, &st))
+ return gsc_config_open;
file.fp = fopen (config_file, "r");
if (!file.fp)
@@ -155,6 +167,9 @@ gsc_config_parse (const char *config_file,
file.buf = NULL;
file.size = 0;
file.line = 0;
+ file.ino = st.st_ino;
+ file.dev = st.st_dev;
+ file.prev = NULL;
file.file_name = config_file;
file.error_msg = errmsg ? errmsg : default_error_msg;
file.error_count = 0;
diff --git a/lib/cfgincl.c b/lib/cfgincl.c
new file mode 100644
index 0000000..b77856a
--- /dev/null
+++ b/lib/cfgincl.c
@@ -0,0 +1,109 @@
+/* This file is part of GSC
+ Copyright (C) 2007 Sergey Poznyakoff
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include "xalloc.h"
+#include "gsc.h"
+
+static gsc_config_file_t *
+find_stat (struct stat *st, gsc_config_file_t *file)
+{
+ for (; file; file = file->prev)
+ if (st->st_dev == file->dev && st->st_ino == file->ino)
+ break;
+ return file;
+}
+
+int
+cfg_include_start (gsc_config_file_t *new_file,
+ gsc_config_file_t *file, char *name)
+{
+ gsc_config_file_t *p;
+ struct stat st;
+
+ if (stat (name, &st))
+ {
+ file->error_msg (file->file_name, file->line,
+ "cannot stat `%s': %s", name, strerror (errno));
+ file->error_count++;
+ return 1;
+ }
+
+ if ((p = find_stat (&st, file)))
+ {
+ file->error_msg (file->file_name, file->line, "recursive inclusion");
+ if (p->prev)
+ file->error_msg (p->prev->file_name, p->prev->line,
+ "`%s' already included here",
+ name);
+ file->error_count++;
+ return 1;
+ }
+
+ new_file->fp = fopen (name, "r");
+ if (!new_file->fp)
+ {
+ file->error_msg (file->file_name, file->line, "cannot open `%s': %s",
+ name, strerror (errno));
+ file->error_count++;
+ return;
+ }
+
+ new_file->buf = NULL;
+ new_file->size = 0;
+ new_file->line = 0;
+ new_file->ino = st.st_ino;
+ new_file->dev = st.st_dev;
+ new_file->prev = file;
+ new_file->file_name = name;
+ new_file->error_msg = file->error_msg;
+ new_file->error_count = file->error_count;
+
+ return 0;
+}
+
+gsc_config_file_t *
+cfg_include_stop (gsc_config_file_t *file)
+{
+ free (file->buf);
+ fclose (file->fp);
+
+ file->prev->error_count = file->error_count;
+ return file->prev;
+}
+
+void
+cfg_include_handler (gsc_config_file_t *file, char *kw, char *val, void *data)
+{
+ gsc_config_file_t new_file;
+
+ if (cfg_include_start (&new_file, file, val))
+ return;
+
+ gsc_config_parse_block (&new_file, data, file->kwtab, NULL);
+
+ cfg_include_stop (&new_file);
+}
+
diff --git a/lib/gsc.h b/lib/gsc.h
index 57e4bc6..3afe5c7 100644
--- a/lib/gsc.h
+++ b/lib/gsc.h
@@ -59,11 +59,16 @@ typedef struct cfg_file
FILE *fp;
const char *file_name;
unsigned line;
+ dev_t dev;
+ ino_t ino;
+ struct cfg_file *prev;
char *buf;
size_t size;
void (*error_msg) (const char *name, unsigned line, const char *fmt, ...)
GSC_PRINTFLIKE(3,4);
- unsigned error_count;
+ unsigned error_count;
+
+ struct gsc_config_keyword *kwtab;
}
gsc_config_file_t;
@@ -91,3 +96,9 @@ gsc_config_status_t gsc_config_parse (const char *config_file,
void (*errmsg) (const char *, unsigned,
const char *, ...),
struct gsc_config_keyword *kwh);
+
+void cfg_include_handler (gsc_config_file_t *file, char *kw, char *val,
+ void *data);
+int cfg_include_start (gsc_config_file_t *new_file,
+ gsc_config_file_t *file, char *name);
+gsc_config_file_t *cfg_include_stop (gsc_config_file_t *pfile);

Return to:

Send suggestions and report system problems to the System administrator.