aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2014-03-07 14:26:14 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2014-03-07 14:26:14 +0200
commitd889f8b28786ff2e95e2a7e3c5e6c9f33e8342a1 (patch)
treed3bb4ed4b76b13ef40c05653444fb7411f507e11
parent42838abb7a3edeecec17123c3c03577855176e99 (diff)
downloadvcsync-d889f8b28786ff2e95e2a7e3c5e6c9f33e8342a1.tar.gz
vcsync-d889f8b28786ff2e95e2a7e3c5e6c9f33e8342a1.tar.bz2
Allow admins to define new .checkoutrc keywords.
* Makefile.am: Add distuninstallcheck_listfiles. * src/Makefile.am (EXTRA_DIST): Add vcsync.conf (install-data-local): New rule. * src/vcsync.conf: New file. * src/checkoutrc.c (kwtab): Set fixed size. Remove all verbatim and text keywords. These should be defined in the configuration file. * src/config.c: New statement "define". * src/vcsync.h (MAX_CHECKOUTRC_KW): New define. * tests/atlocal.in (DFL_VCSYNC_CONF): New variable. * tests/checkoutrc-rec.at: Use ../src/vcsync.conf * tests/checkoutrc.at: Likewise. * tests/testsuite.at: Include src/vcsync.conf in all configuration files. * doc/vcsync.8: Update. * doc/vcsync.conf.5: Document the "define" statement.
-rw-r--r--Makefile.am2
-rw-r--r--doc/vcsync.815
-rw-r--r--doc/vcsync.conf.520
-rw-r--r--src/Makefile.am8
-rw-r--r--src/checkoutrc.c43
-rw-r--r--src/config.c66
-rw-r--r--src/vcsync.conf18
-rw-r--r--src/vcsync.h3
-rw-r--r--tests/atlocal.in1
-rw-r--r--tests/checkoutrc-rec.at2
-rw-r--r--tests/checkoutrc.at2
-rw-r--r--tests/testsuite.at3
12 files changed, 161 insertions, 22 deletions
diff --git a/Makefile.am b/Makefile.am
index 0959c14..8406ca3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -18,6 +18,8 @@ ACLOCAL_AMFLAGS = -I grecs/am
SUBDIRS=grecs src tests doc
+distuninstallcheck_listfiles = find . -type f -not -name 'vcsync.conf' -print
+
.PHONY: ChangeLog
ChangeLog:
$(AM_V_GEN)if test -d .git; then \
diff --git a/doc/vcsync.8 b/doc/vcsync.8
index 58b094d..e5df993 100644
--- a/doc/vcsync.8
+++ b/doc/vcsync.8
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with Vcsync. If not, see <http://www.gnu.org/licenses/>.
-.TH VCSYNC 8 "March 6, 2014" "VCSYNC"
+.TH VCSYNC 8 "March 7, 2014" "VCSYNC"
.SH NAME
vcsync \- synchronize version control system updates with the file system
.SH SYNOPSIS
@@ -373,10 +373,17 @@ number. Shell wildcards are allowed in \fIfile\fR arguments. After
expandind, each file argument must refer to a file in the current
directory or one of its subdirectories.
.PP
-The statements below cause creation of
+The administrator can also define additional keywords, as described in
+.BR vcsync.conf (5),
+subsection
+.BR "Checkoutrc keywords" .
+Appearance of these user-defined keywords in the \fB.checkoutrc\fR
+file cause creation and modification of the
.B .htaccess
file in the current directory.
.PP
+The default configuration file shipped with the distribution defines
+the following keywords:
.TP
\fBxbithack\fR \fBon\fR|\fBoff\fR
If set to \fBon\fR, adds the following to
@@ -418,10 +425,6 @@ verbatim:
\fBrewriterule\fR \fIargs\fR...
.ad
.hy
-
-
-
-
.SH "EXIT CODE"
.IP 0
Successful termination.
diff --git a/doc/vcsync.conf.5 b/doc/vcsync.conf.5
index 5325f5e..3fe893c 100644
--- a/doc/vcsync.conf.5
+++ b/doc/vcsync.conf.5
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with Vcsync. If not, see <http://www.gnu.org/licenses/>.
-.TH VCSYNC.CONF 5 "March 5, 2014" "VCSYNC.CONF"
+.TH VCSYNC.CONF 5 "March 7, 2014" "VCSYNC.CONF"
.SH NAME
vcsync.conf \- configuration file for vcsync
.SH DESCRIPTION
@@ -287,6 +287,24 @@ as follows:
vcsync --name alt [\fIother arguments\fR]
.EE
.RE
+.SS Checkoutrc keywords
+The syntax of \fB.checkoutrc\fR files can be expanded with new keywords,
+if the need be. There are two kinds of keywords: \fBverbatim\fR
+and \fBboolean\fR. Verbatim keywords cause the entire line from
+\fB.checkoutrc\fR to be reproduced in \fB.htaccess\fR. Boolean
+ones take a boolean value as their argument. If that value evaluates
+to true, a text assigned to the keyword is inserted in the current
+position of \fB.htaccess\fR. Otherwise, the keyword is ignored.
+.PP
+You can use the \fBdefine\fR statement to define new \fB.checkoutrc\fR
+keywords. Please do so sparingly and consider possible security
+implications.
+.TP
+\fBdefine\fR \fIkeyword\fB;\fR
+Define a verbatim keyword.
+.TP
+\fBdefine\fR \fIkeyword\fR \fItext\fB;\fR
+Define a boolean keyword.
.SS Logging
The following configuration statement controls the \fBsyslog\fR output:
.sp
diff --git a/src/Makefile.am b/src/Makefile.am
index 217ad92..d8d468e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,9 +34,15 @@ AM_CPPFLAGS=\
-DSYSCONFDIR=\"$(sysconfdir)\"
BUILT_SOURCES=cmdline.h
-EXTRA_DIST=cmdline.opt
+EXTRA_DIST=cmdline.opt vcsync.conf
SUFFIXES=.opt .c .h
.opt.h:
$(AM_V_GEN)m4 -s $(top_srcdir)/@GRECS_SUBDIR@/build-aux/getopt.m4 $< > $@
+install-data-local:
+ @test -z "$(DESTDIR)$(sysconfdir)" || $(mkdir_p) "$(DESTDIR)$(sysconfdir)"
+ @if [ -r $(DESTDIR)$(sysconfdir)/vcsync.conf ]; then :; \
+ else ${INSTALL} -m 644 $(top_srcdir)/src/vcsync.conf \
+ $(DESTDIR)$(sysconfdir)/vcsync.conf; fi
+
diff --git a/src/checkoutrc.c b/src/checkoutrc.c
index a7563b8..3fdc2a9 100644
--- a/src/checkoutrc.c
+++ b/src/checkoutrc.c
@@ -285,24 +285,43 @@ kwf_chmod(struct stmt_env *env)
}
-static struct keyword kwtab[] = {
+static struct keyword kwtab[MAX_CHECKOUTRC_KW] = {
{ "link", KW_HANDLER, { handler: kwf_link } },
{ "unlink", KW_HANDLER, { handler: kwf_unlink } },
{ "chmod", KW_HANDLER, { handler: kwf_chmod } },
- { "xbithack", KW_TEXT, { text: "Options +IncludesNOEXEC\n"
- "XBitHack On" } },
- { "ssi", KW_TEXT,
- { text: "AddHandler server-parsed .html" } },
- { "redirect", KW_VERBATIM },
- { "rewritebase", KW_VERBATIM },
- { "rewritecond", KW_VERBATIM },
- { "rewriteengine", KW_VERBATIM },
- { "rewritemap", KW_VERBATIM },
- { "rewriteoptions", KW_VERBATIM },
- { "rewriterule", KW_VERBATIM },
{ NULL }
};
+int
+checkoutrc_register_keyword(const char *name, char *text)
+{
+ struct keyword *kp;
+
+ for (kp = kwtab; kp->name; kp++) {
+ if (strcasecmp(kp->name, name) == 0) {
+ errno = EEXIST;
+ return -1;
+ }
+ }
+ if (kp - kwtab == MAX_CHECKOUTRC_KW) {
+ errno = EMFILE;
+ return -1;
+ }
+ kp->name = estrdup(name);
+ if (text) {
+ size_t len;
+
+ kp->type = KW_TEXT;
+ kp->v.text = estrdup(text);
+ len = strlen(kp->v.text);
+ if (kp->v.text[len-1] == '\n')
+ kp->v.text[len-1] = 0;
+ } else {
+ kp->type = KW_VERBATIM;
+ }
+ return 0;
+}
+
static struct keyword *
keyword_locate(const char *name)
{
diff --git a/src/config.c b/src/config.c
index 2958502..62bf189 100644
--- a/src/config.c
+++ b/src/config.c
@@ -80,6 +80,67 @@ cb_vcs_type(enum grecs_callback_command cmd, grecs_node_t *node,
return 0;
}
+static int
+cb_define(enum grecs_callback_command cmd, grecs_node_t *node,
+ void *varptr, void *cb_data)
+{
+ grecs_locus_t *locus = &node->locus;
+ grecs_value_t *value = node->v.value;
+ int rc;
+
+ ASSERT_SCALAR(cmd, locus);
+ switch (value->type) {
+ case GRECS_TYPE_STRING:
+ rc = checkoutrc_register_keyword(value->v.string, NULL);
+ break;
+
+ case GRECS_TYPE_ARRAY:
+ switch (value->v.arg.c) {
+ case 1:
+ if (assert_grecs_value_type(&value->v.arg.v[0]->locus,
+ value->v.arg.v[0],
+ GRECS_TYPE_STRING))
+ return 1;
+ rc = checkoutrc_register_keyword
+ (value->v.arg.v[0]->v.string, NULL);
+ break;
+ case 2:
+ if (assert_grecs_value_type(&value->v.arg.v[0]->locus,
+ value->v.arg.v[0],
+ GRECS_TYPE_STRING))
+ return 1;
+ if (assert_grecs_value_type(&value->v.arg.v[1]->locus,
+ value->v.arg.v[1],
+ GRECS_TYPE_STRING))
+ return 1;
+ rc = checkoutrc_register_keyword
+ (value->v.arg.v[0]->v.string,
+ value->v.arg.v[1]->v.string);
+ break;
+ default:
+ grecs_error(locus, 0, "too many arguments");
+ return 1;
+ }
+ break;
+
+ default:
+ return 1;
+ }
+
+ if (rc) {
+ switch (errno) {
+ case EMFILE:
+ grecs_error(locus, 0, "too many keywords defined");
+ break;
+ case EEXIST:
+ grecs_error(locus, 0, "keyword already defined");
+ break;
+ }
+ }
+
+ return rc;
+}
+
int
get_facility(const char *arg, int *retval)
{
@@ -277,6 +338,11 @@ static struct grecs_keyword vcsync_kw[] = {
{ "config", "name: string", "Define a named configuration",
grecs_type_section, GRECS_DFLT, NULL, 0, cb_config, NULL,
vcsync_config_kw },
+
+ { "define", "<kw: string> [<text: string>]",
+ "Define checkoutrc keyword",
+ grecs_type_string, GRECS_DFLT,
+ NULL, 0, cb_define },
{ "syslog", NULL, "Configure syslog logging",
grecs_type_section, GRECS_DFLT, NULL, 0, NULL, NULL, syslog_kw },
diff --git a/src/vcsync.conf b/src/vcsync.conf
new file mode 100644
index 0000000..8fbd007
--- /dev/null
+++ b/src/vcsync.conf
@@ -0,0 +1,18 @@
+# Default vcsync.conf (5) file
+
+define xbithack <<EOT
+Options +IncludesNOEXEC
+XBitHack On
+EOT;
+
+define ssi <<EOT
+AddHandler server-parsed .html
+EOT;
+
+define redirect;
+define rewritebase;
+define rewritecond;
+define rewriteengine;
+define rewritemap;
+define rewriteoptions;
+define rewriterule;
diff --git a/src/vcsync.h b/src/vcsync.h
index 1624f1a..48cd9a9 100644
--- a/src/vcsync.h
+++ b/src/vcsync.h
@@ -18,6 +18,8 @@
#define EX_USAGE 2
#define EX_CONFIG 3
+#define MAX_CHECKOUTRC_KW 512
+
extern int debug_level;
extern int dry_run;
extern const char *progname;
@@ -105,6 +107,7 @@ void checkoutrc(const char *, const char *);
void register_directory(const char *dir, int recursive);
void flush_checkoutrc_files(const char *);
int have_checkoutrc(void);
+int checkoutrc_register_keyword(const char *name, char *text);
diff --git a/tests/atlocal.in b/tests/atlocal.in
index b47c60d..2906235 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -9,3 +9,4 @@ TESTDIR=@abs_top_builddir@/tests
CVS_BIN=@CVS_BIN@
SVN_BIN=@SVN_BIN@
GIT_BIN=@GIT_BIN@
+DFL_VCSYNC_CONF=@abs_top_srcdir@/src/vcsync.conf
diff --git a/tests/checkoutrc-rec.at b/tests/checkoutrc-rec.at
index 602d6d2..5cf7c76 100644
--- a/tests/checkoutrc-rec.at
+++ b/tests/checkoutrc-rec.at
@@ -47,7 +47,7 @@ EOT
cd ../..
set -e
-vcsync -e -c /dev/null -w $cwd/home -D test/ -d 2>err
+vcsync -e -c $DFL_VCSYNC_CONF -w $cwd/home -D test/ -d 2>err
sed "s|$cwd/||" err >&2
test -x home/test/x && echo "x OK"
diff --git a/tests/checkoutrc.at b/tests/checkoutrc.at
index f97eca8..4750410 100644
--- a/tests/checkoutrc.at
+++ b/tests/checkoutrc.at
@@ -38,7 +38,7 @@ EOT
cd ../..
set -e
-vcsync -e -c /dev/null -w $cwd/home -D test -d 2>err
+vcsync -e -c $DFL_VCSYNC_CONF -w $cwd/home -D test -d 2>err
sed "s|$cwd/||" err >&2
test -x home/test/x && echo "x OK"
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 03de53c..8bb57d8 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -35,6 +35,7 @@ mkdir test repo home repo/test
# Create configuration file
cat > vcsync.conf <<EOT
+#include $DFL_VCSYNC_CONF
detach yes;
sleep 2;
vcs-type cvs;
@@ -81,6 +82,7 @@ mkdir repo home
# Create configuration file
cat > vcsync.conf <<EOT
+#include $DFL_VCSYNC_CONF
vcs-type svn;
destination-root $cwd/home;
debug ${VCSYNC_TESTSUITE_DEBUG:-0};
@@ -118,6 +120,7 @@ mkdir repo home test
# Create configuration file
cat > vcsync.conf <<EOT
+#include $DFL_VCSYNC_CONF
vcs-type git;
destination-root $cwd/home;
debug ${VCSYNC_TESTSUITE_DEBUG:-0};

Return to:

Send suggestions and report system problems to the System administrator.