aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac10
-rw-r--r--doc/Makefile.am21
-rw-r--r--doc/wydawca.texi46
-rw-r--r--etc/wydawca.rc90
-rw-r--r--gnulib.modules1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/cmdline.opt18
-rw-r--r--src/mail.c22
-rw-r--r--src/meta.c183
-rw-r--r--src/triplet.c171
-rw-r--r--src/update-2.0.awk7
-rw-r--r--src/verify.c251
-rw-r--r--src/wydawca.c28
-rw-r--r--src/wydawca.h19
-rw-r--r--tests/.gitignore6
-rw-r--r--tests/Makefile.am67
-rw-r--r--tests/atlocal.in9
-rw-r--r--tests/etc/.gitignore2
-rw-r--r--tests/etc/Makefile.am27
-rw-r--r--tests/etc/pubring.asc30
-rw-r--r--tests/etc/secring.asc31
-rw-r--r--tests/testsuite.at25
-rw-r--r--tests/version.at34
24 files changed, 686 insertions, 415 deletions
diff --git a/Makefile.am b/Makefile.am
index 827c17d..1eac948 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,7 +17,7 @@
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = gnu 1.8.5
-SUBDIRS=gnu gconf src doc etc
+SUBDIRS=gnu gconf src doc etc tests
# We never remove files from the configuration directory
distuninstallcheck_listfiles = \
diff --git a/configure.ac b/configure.ac
index bc612af..d72e815 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,6 +159,16 @@ AH_BOTTOM([
#endif
])
+# Initialize the test suite.
+AC_CONFIG_TESTDIR(tests)
+AC_CONFIG_FILES([tests/Makefile tests/atlocal tests/etc/Makefile])
+AM_MISSING_PROG([AUTOM4TE], [autom4te])
+
+AC_PATH_PROG(GPG, gpg, '')
+if test -n "$GPG"; then
+ AC_SUBST(WYDAWCA_GPGFILES, '$(GPGFILES)')
+fi
+
AC_CONFIG_FILES([Makefile
doc/Makefile
gnu/Makefile
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7c7b135..7afd676 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,5 +1,5 @@
# This file is part of Wydawca
-# Copyright (C) 2007 Sergey Poznyakoff
+# Copyright (C) 2007, 2009 Sergey Poznyakoff
#
# Wudawca 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
@@ -49,9 +49,9 @@ check-format:
check-options:
@check-docs.sh options \
- '/option options\[\] = /,/^}/s/[ \t]*{ *"\([^,"]*\)".*/\1/pg' \
- 's/@opindex *\([^@,]*\), --.*/\1/p' \
- $(top_srcdir)/src/wydawca.c -- \
+ '/OPTIONS_BEGIN/,/OPTIONS_END/s/OPTION( *\([^,][^,]*\),.*/\1/pg' \
+ '/@c option --/{s///;s/^\(help\|version\|usage\)//;p}' \
+ $(top_srcdir)/src/cmdline.opt -- \
$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -E - \
$(info_TEXINFOS)
@@ -69,6 +69,17 @@ check-fixmes:
fi
rm -f $@-t
+check-writeme:
+ @grep -Hn @WRITEME $(info_TEXINFOS) $(mailfromd_TEXINFOS) > $@-t; \
+ if [ -s $@-t ]; then \
+ echo "Empty nodes:"; \
+ cat $@-t; \
+ rm $@-t; \
+ false;\
+ else \
+ rm $@-t; \
+ fi
+
check-unrevised:
@grep -Hn @UNREVISED $(info_TEXINFOS) > $@-t; \
if [ -s $@-t ]; then \
@@ -80,7 +91,7 @@ check-unrevised:
rm $@-t; \
fi
-all-check-docs: check-format check-options check-refs check-fixmes check-unrevised
+all-check-docs: check-format check-options check-refs check-fixmes check-unrevised check-writeme
check-docs:
$(MAKE) -k all-check-docs
diff --git a/doc/wydawca.texi b/doc/wydawca.texi
index e54cc8e..3f5a682 100644
--- a/doc/wydawca.texi
+++ b/doc/wydawca.texi
@@ -337,6 +337,7 @@ $ wydawca -c new.cfg --dry-run
@node configuring, wydawca.rc, starting, Top
@chapter How to Configure @command{wydawca}.
+@UNREVISED
The @command{wydawca} configuration file has a simple line-oriented
syntax. Empty lines are ignored. Comments are introduced by a pound
sign (@samp{#}): everything starting from the first occurrence of
@@ -398,7 +399,8 @@ configuration on a step-by-step basis.
@section Include Statement
@cindex inclusion, configuration file
@kwindex include
- You can request inclusion of any file into your configuration file
+@UNREVISED
+You can request inclusion of any file into your configuration file
using @code{include} statement. Its only argument supplies the name of
file to be included. For example:
@@ -466,7 +468,8 @@ effect.
@section Syslog Configuration Directives
@cindex syslog, configuration
@kwindex syslog-facility
- Unless told otherwise, @command{wydawca} uses @code{syslog} to print
+@UNREVISED
+Unless told otherwise, @command{wydawca} uses @code{syslog} to print
its diagnostic messages. By default, the program uses the
@samp{local1} facility. To change this, use @code{syslog-facility}
statement:
@@ -513,7 +516,8 @@ syslog-print-priority yes
@cindex @acronym{SQL} databases
@cindex @command{MySQL} databases
@cindex database, @command{MySQL}
- Several statements in configuration file may need to access
+@UNREVISED
+Several statements in configuration file may need to access
@acronym{SQL} database. @command{Wydawca} can use any number of
databases simultaneously, the only restriction being that they must be
@command{MySQL} databases (this restriction will be removed in future
@@ -578,7 +582,8 @@ end
@section Access Methods
@cindex Access method
@cindex @acronym{PGP} key
- An @dfn{access method} defines how @command{wydawca} accesses some
+@UNREVISED
+An @dfn{access method} defines how @command{wydawca} accesses some
piece of information it needs while verifying the submission. This
information can be, for example, the user's @acronym{PGP} key or his
permissions on a project.
@@ -736,7 +741,8 @@ verify-user sql default SELECT user.user_name \
@cindex sendfile
@cindex Invalid value, warning message
@cindex Function not implemented, warning message
- If compiled for GNU/Linux, @command{wydawca} tries to optimize disk
+@UNREVISED
+If compiled for GNU/Linux, @command{wydawca} tries to optimize disk
transfer operations by using @code{sendfile} system call. If it
fails, and the error is recoverable, @command{wydawca} falls back to
copying files using user space. This is indicated by one of the following
@@ -764,7 +770,8 @@ higher.
@node archivation
@section Archivation
@cindex archivation, defined
- There may be cases when project maintainers need to overwrite
+@UNREVISED
+There may be cases when project maintainers need to overwrite
existing distributed files with another ones, having the same names.
(Note, hovewer, that this practice is not encouraged). In that case,
@command{wydawca} needs to first @dfn{archive} the already existing
@@ -913,7 +920,8 @@ archive-signatures no
@cindex source directory, defining
@kwindex source
@kwindex destination
- A @dfn{directory pair} definition is a core of @command{wydawca}
+@UNREVISED
+A @dfn{directory pair} definition is a core of @command{wydawca}
configuration. It defines the location of the source directory and the
corresponding distribution (or @dfn{destination}) directory. It may
also set the archivation type being used for that directory and
@@ -971,7 +979,8 @@ provisions for such case.
@node statistics
@section Statistics
@cindex statistics
- At the end of the run, @command{wydawca} prints a detailed
+@UNREVISED
+At the end of the run, @command{wydawca} prints a detailed
statistics of its execution on the diagnostic channel @samp{info}.
The statistics is printed only if at least one of the items is not zero.
The following example illustrates what you might get if you configured
@@ -1100,7 +1109,8 @@ statistics all errors warnings
@node notification
@section Mail Notification
@cindex mail notification
- While running, @command{wydawca} keeps track of certain events
+@UNREVISED
+While running, @command{wydawca} keeps track of certain events
occurring, such as, for example, broken @acronym{PGP} signatures or
file uploads attempted by unauthorized users. The utility can notify,
via email, project administrators about any of those events that
@@ -1133,7 +1143,8 @@ from the name of the user @command{wydawca} runs as (usually
@subsection Mailer
@cindex mailer
@kwindex mailer
- To send messages, @command{wydawca} uses a special logical entity
+@UNREVISED
+To send messages, @command{wydawca} uses a special logical entity
called @dfn{mailer}. It is set in the configuration file using
@code{mailer} keyword:
@@ -1199,7 +1210,8 @@ mailer smtp://remote.server.net:24
@cindex templates, notification messages
@cindex notification message template
@cindex message template
- Each notification message is build from a message template, by
+@UNREVISED
+Each notification message is build from a message template, by
expanding any occurrences of @samp{%@{@var{name}@}} within it with the value
of macro-variable @var{name}. Sets of defined macro-variables
depend on the type of the notification and are described below.
@@ -1262,7 +1274,8 @@ EOT
@node statreports
@subsection Statistic Reports
@kwindex mail-admin-stat
- Sending statistic reports to the system administrator is enabled by
+@UNREVISED
+Sending statistic reports to the system administrator is enabled by
@code{mail-admin-stat} statement. It takes two or more arguments.
The first argument supplies the identifier of a message template,
which should be previously defined by a @code{define-message}.
@@ -1347,7 +1360,8 @@ end
@node event notification
@subsection Event Notification
@cindex event notification
- The following @dfn{events} are tracked during the execution. Any of
+@UNREVISED
+The following @dfn{events} are tracked during the execution. Any of
them can be used to trigger an email notification of any party
concerned: the system administrator, project administrators, or
the user that initiated the upload:
@@ -1517,7 +1531,8 @@ notify-event success user user-success
@node wydawca.rc, invocation, configuring, Top
@chapter @command{Wydawca} configuration file.
@cindex configuration statements, reference
- This chapter contains a concise reference list of all configuration
+@UNREVISED
+This chapter contains a concise reference list of all configuration
file statements.
@deffn {Wydawca Statement} archive @var{type} @var{archive-name} @
@@ -1866,7 +1881,8 @@ Sets the mailer @acronym{URL} to use.
@chapter @command{Wydawca} invocation summary.
@cindex invocation
@cindex command line options
- This chapter presents a short reference of all @command{wydawca}
+@UNREVISED
+This chapter presents a short reference of all @command{wydawca}
command line options, in alphabetical order.
@table @option
diff --git a/etc/wydawca.rc b/etc/wydawca.rc
index c722fa6..205c4e0 100644
--- a/etc/wydawca.rc
+++ b/etc/wydawca.rc
@@ -59,13 +59,13 @@ access-method project-owner {
"WHERE user_group.user_id=user.user_id "
"AND user_group.group_id=groups.group_id "
"AND user_group.admin_flags = 'A' "
- "AND groups.unix_group_name='%p'");
+ "AND groups.unix_group_name='$p'");
}
access-method user-data {
type sql;
params (default,
- "SELECT email, realname FROM user WHERE user_name='%{user}'");
+ "SELECT email, realname FROM user WHERE user_name='${user}'");
}
access-method verify-user {
@@ -76,13 +76,13 @@ access-method verify-user {
"WHERE user_group.user_id=user.user_id "
"AND user_group.group_id=groups.group_id "
"AND user_group.admin_flags = 'A' "
- "AND groups.unix_group_name='%p' AND user.user_name='%u'");
+ "AND groups.unix_group_name='$p' AND user.user_name='$u'");
}
access-method gpg-key {
type sql;
params (default,
- "SELECT gpg_key FROM user WHERE user_name='%u'");
+ "SELECT gpg_key FROM user WHERE user_name='$u'");
}
#############################################################################
@@ -116,22 +116,22 @@ mail-statistics {
message <<EOT
Subject: Wydawca stats
-This is to notify you that the run of wydawca on %{date}
+This is to notify you that the run of wydawca on ${date}
caused the following results:
-errors ............................. %{stat:errors}
-warning ............................ %{stat:warnings}
-bad signatures ..................... %{stat:bad_signatures}
-access violation attempts .......... %{stat:access_violations}
-complete triplets .................. %{stat:complete_triplets}
-incomplete triplets ................ %{stat:incomplete_triplets}
-bad triplets ....................... %{stat:bad_triplets}
-expired triplets ................... %{stat:expired_triplets}
-triplet successes .................. %{stat:triplet_success}
-files uploaded ..................... %{stat:uploads}
-files archived ..................... %{stat:archives}
-symlinks created ................... %{stat:symlinks}
-symlinks removed ................... %{stat:rmsymlinks}
+errors ............................. ${stat:errors}
+warning ............................ ${stat:warnings}
+bad signatures ..................... ${stat:bad_signatures}
+access violation attempts .......... ${stat:access_violations}
+complete triplets .................. ${stat:complete_triplets}
+incomplete triplets ................ ${stat:incomplete_triplets}
+bad triplets ....................... ${stat:bad_triplets}
+expired triplets ................... ${stat:expired_triplets}
+triplet successes .................. ${stat:triplet_success}
+files uploaded ..................... ${stat:uploads}
+files archived ..................... ${stat:archives}
+symlinks created ................... ${stat:symlinks}
+symlinks removed ................... ${stat:rmsymlinks}
Regards,
Wydawca
@@ -145,11 +145,11 @@ notify-event {
event success;
recipient user;
message <<EOT
-Subject: Upload of %{project} successful
+Subject: Upload of ${project} successful
-Upload of %{project} to %{dir} finished successfully. Files uploaded:
+Upload of ${project} to ${dir} finished successfully. Files uploaded:
-%{triplet:upload}
+${triplet:upload}
Regards,
Wydawca
@@ -162,12 +162,12 @@ notify-event {
event success;
recipient owner;
message <<EOT
-Subject: Upload of %{project} successful
+Subject: Upload of ${project} successful
-%{user:real-name} (%{user:email}) successfully uploaded files
-for %{project} to %{dir}. Files uploaded:
+${user:real-name} (${user:email}) successfully uploaded files
+for ${project} to ${dir}. Files uploaded:
-%{triplet:upload}
+${triplet:upload}
Regards,
Wydawca
@@ -181,17 +181,17 @@ notify-event {
event bad-ownership;
recipient owner;
message <<EOT
-Subject: Suspicious upload of %{project}
+Subject: Suspicious upload of ${project}
-Someone not authorized to make releases for %{project}
-has attempted to upload the following files to %{dir}:
+Someone not authorized to make releases for ${project}
+has attempted to upload the following files to ${dir}:
-%{triplet:full}
+${triplet:full}
This upload has been ignored and the files removed. The person who attempted
-the upload was %{user:real-name}, user name %{user:name}, email %{user:email}.
+the upload was ${user:real-name}, user name ${user:name}, email ${user:email}.
If you think this is an error and wish this user to be authorized to make
-releases for %{project}, please contact <puszcza-hackers@gnu.org.ua>.
+releases for ${project}, please contact <puszcza-hackers@gnu.org.ua>.
Otherwise, let us know so we could undertake appropriate measures.
Regards,
@@ -209,13 +209,13 @@ notify-event {
event bad-directive-signature;
recipient user;
message <<EOT
-Subject: Suspicious upload of %{project}
+Subject: Suspicious upload of ${project}
-Someone (apparently you), has tried to make a release for %{project}.
+Someone (apparently you), has tried to make a release for ${project}.
However, the signature of the directive file was wrong, which looks
suspicious. The person uploaded the following files:
-%{triplet:full}
+${triplet:full}
This upload has been ignored and the files removed. If it was you who
attempted this upload, please make sure you use the right PGP key and
@@ -234,13 +234,13 @@ notify-event {
event bad-directive-signature;
recipient owner;
message <<EOT
-Subject: Suspicious upload of %{project}
+Subject: Suspicious upload of ${project}
-%{user:real-name} (%{user:email}) has tried to make a release
-for %{project}. However, the signature of the directive file was wrong,
+${user:real-name} (${user:email}) has tried to make a release
+for ${project}. However, the signature of the directive file was wrong,
which looks suspicious. The person uploaded the following files:
-%{triplet:full}
+${triplet:full}
This upload has been ignored and the files removed.
@@ -259,13 +259,13 @@ notify-event {
event bad-detached-signature;
recipient user;
message <<EOT
-Subject: Suspicious upload of %{project}
+Subject: Suspicious upload of ${project}
-Someone (apparently you), has tried to make a release for %{project}.
+Someone (apparently you), has tried to make a release for ${project}.
However, the detached signature signature was wrong, which looks
suspicious. The person uploaded the following files:
-%{triplet:full}
+${triplet:full}
This upload has been ignored and the files removed. If it was you who
attempted this upload, please make sure you use the right PGP key and
@@ -284,13 +284,13 @@ notify-event {
event bad-detached-signature;
recipient owner;
message <<EOT
-Subject: Suspicious upload of %{project}
+Subject: Suspicious upload of ${project}
-%{user:real-name} (%{user:email}) has tried to make a release
-for %{project}. However, the detached signature file was wrong,
+${user:real-name} (${user:email}) has tried to make a release
+for ${project}. However, the detached signature file was wrong,
which looks suspicious. The person uploaded the following files:
-%{triplet:full}
+${triplet:full}
This upload has been ignored and the files removed.
diff --git a/gnulib.modules b/gnulib.modules
index 73eaa4e..7480221 100644
--- a/gnulib.modules
+++ b/gnulib.modules
@@ -1,4 +1,5 @@
xalloc
+c-ctype
obstack
getopt
gitlog-to-changelog
diff --git a/src/Makefile.am b/src/Makefile.am
index 10a6b60..67e21e0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,7 @@ wydawca_SOURCES=\
exec.c\
gpg.c\
interval.c\
+ meta.c\
method.c\
process.c\
sql.c\
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 00bbedc..ddffe33 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -62,6 +62,24 @@ BEGIN
log_to_stderr = 1;
END
+OPTION(preprocessor,,COMMAND,
+ [<use COMMAND instead of the default preprocessor>])
+BEGIN
+ gconf_preprocessor = optarg;
+END
+
+OPTION(no-preprocessor,,,
+ [<disable preprocessing>])
+BEGIN
+ gconf_preprocessor = NULL;
+END
+
+OPTION(,E,,
+ [<preprocess config and exit>])
+BEGIN
+ preprocess_only = 1;
+END
+
OPTION(dump-grammar-trace,,,
[<dump configuration grammar traces>])
BEGIN
diff --git a/src/mail.c b/src/mail.c
index e0a0b8a..619fba4 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -215,7 +215,7 @@ register_notification (const struct notification *notif)
void
mail_stats ()
{
- struct kw_expansion exp[MAX_STAT + 1];
+ struct metadef exp[MAX_STAT + 2];
time_t t;
const char *tmpl;
char *text;
@@ -238,10 +238,10 @@ mail_stats ()
return;
time (&t);
+ memset (exp, 0, sizeof (exp));
exp[0].kw = "date";
- exp[0].value = xstrdup (ctime (&t));
+ exp[0].value = exp[0].storage = xstrdup (ctime (&t));
exp[0].value [strlen (exp[0].value) - 1] = 0;
- exp[0].expand = NULL;
make_stat_expansion (exp + 1);
@@ -252,13 +252,12 @@ mail_stats ()
admin_stat_message);
return;
}
- text = expand_param (tmpl,
- exp, sizeof (exp) / sizeof (exp[0]), NULL);
+ text = meta_expand_string (tmpl, exp, NULL);
mail_send_message (admin_address, text);
free (text);
- free_kwexp (exp, sizeof (exp) / sizeof (exp[0]));
+ meta_free (exp);
}
mu_address_t
@@ -266,7 +265,7 @@ get_recipient (struct access_method *method, struct file_triplet *trp,
char **errp)
{
unsigned nrows, ncols, i;
- struct kw_expansion kwexp[4];
+ struct metadef def[5];
mu_address_t rcpt = NULL;
char *text;
int rc;
@@ -283,10 +282,11 @@ get_recipient (struct access_method *method, struct file_triplet *trp,
return NULL;
}
- make_default_kwexp (kwexp, trp->user, trp->project);
- escape_kwexp (method, kwexp, NITEMS (kwexp));
- text = expand_param (method->param[1], kwexp, NITEMS (kwexp), NULL);
-
+ make_default_meta (def, trp->user, trp->project);
+ meta_escape (method, def);
+ text = meta_expand_string (method->param[1], def, NULL);
+ meta_free (def);
+
rc = method_run (method, text);
free (text);
if (rc)
diff --git a/src/meta.c b/src/meta.c
new file mode 100644
index 0000000..4516df2
--- /dev/null
+++ b/src/meta.c
@@ -0,0 +1,183 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff
+
+ Wydawca 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.
+
+ Wydawca 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 wydawca. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "wydawca.h"
+#include "sql.h"
+#define obstack_chunk_alloc malloc
+#define obstack_chunk_free free
+#include <obstack.h>
+#include <c-ctype.h>
+
+static const char *
+meta_expand (struct metadef *def, void *data)
+{
+ if (!def->value)
+ {
+ if (def->expand)
+ return def->expand (def, data);
+ def->value = "INTERNAL ERROR: NONEXPANDABLE DATA";
+ }
+ return def->value;
+}
+
+static const char *
+find_expansion_char (int c, struct metadef *def, void *data)
+{
+ for (; def->kw; def++)
+ if (def->kw[1] == 0 && def->kw[0] == c)
+ return meta_expand (def, data);
+ return NULL;
+}
+
+static const char *
+find_expansion_word (const char *kw, size_t len,
+ struct metadef *def, void *data)
+{
+ for (; def->kw; def++)
+ if (strlen (def->kw) == len && memcmp (def->kw, kw, len) == 0)
+ return meta_expand (def, data);
+ return NULL;
+}
+
+char *
+meta_expand_string (const char *string, struct metadef *def, void *data)
+{
+ const char *p, *s;
+ char *res;
+ struct obstack stk;
+
+ if (!string)
+ return NULL;
+
+ obstack_init (&stk);
+
+ for (p = string; *p;)
+ {
+ char *e;
+ size_t len = strcspn (p, "$");
+
+ obstack_grow (&stk, p, len);
+ p += len;
+ if (*p == '$')
+ {
+ switch (*++p)
+ {
+ case '$':
+ obstack_grow (&stk, p, 1);
+ p++;
+ break;
+
+ case '{':
+ e = strchr (p + 1, '}');
+ if (e && (s = find_expansion_word (p + 1, e - p - 1, def, data)))
+ {
+ obstack_grow (&stk, s, strlen (s));
+ p = e + 1;
+ }
+ else
+ {
+ obstack_grow (&stk, p - 1, 1);
+ p++;
+ }
+ break;
+
+ default:
+ if ((s = find_expansion_char (*p, def, data)) != NULL)
+ len = strlen (s);
+ else
+ {
+ s = p - 1;
+ len = 1;
+ }
+ obstack_grow (&stk, s, len);
+ p++;
+ }
+ }
+ else
+ obstack_grow (&stk, p, 1);
+ }
+ obstack_1grow (&stk, 0);
+ res = xstrdup (obstack_finish (&stk));
+ obstack_free (&stk, NULL);
+ return res;
+}
+
+/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed
+ quoted string. Return its length. */
+static size_t
+quote_string (struct access_method *method, const char *input, char **poutput)
+{
+ size_t size, len;
+ int quote;
+ char *output;
+
+ if (!input)
+ {
+ *poutput = xmalloc (1);
+ (*poutput)[0] = 0;
+ return 1;
+ }
+
+ switch (method->type)
+ {
+ case method_sql:
+ len = strlen (input);
+ size = 2 * len + 1;
+ output = xmalloc (size);
+ mysql_real_escape_string (&method->v.sqlconn->mysql, output, input, len);
+ size = strlen (output);
+ break;
+
+ default:
+ size = argcv_quoted_length (input, &quote);
+ output = xmalloc (size);
+ argcv_quote_copy (output, input);
+ break;
+ }
+
+ *poutput = output;
+ return size;
+}
+
+void
+meta_escape (struct access_method *method, struct metadef *def)
+{
+ for (; def->kw; def++)
+ {
+ if (def->value)
+ {
+ char *newval;
+ quote_string (method, def->value, &newval);
+ if (def->storage)
+ free (def->storage);
+ def->value = def->storage = newval;
+ }
+ }
+}
+
+void
+meta_free (struct metadef *def)
+{
+ for (; def->kw; def++)
+ {
+ if (def->storage)
+ {
+ free (def->storage);
+ def->value = def->storage = NULL;
+ }
+ }
+}
+
diff --git a/src/triplet.c b/src/triplet.c
index 9ac8313..2fafc8f 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -246,38 +246,37 @@ count_collected_triplets ()
}
-static char *
-expand_project_base (struct kw_expansion *exp, void *data)
+static const char *
+expand_project_base (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->project;
}
-static char *
-expand_url (struct kw_expansion *exp, void *data)
+static const char *
+expand_url (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->dpair->url;
}
-static char *
-expand_relative_dir (struct kw_expansion *exp, void *data)
+static const char *
+expand_relative_dir (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- directive_get_value (trp, "directory", (const char**) &exp->value);
- exp->static_p = 1;
- return exp->value;
+ directive_get_value (trp, "directory", (const char**) &def->value);
+ return def->value;
}
-static char *
-expand_dest_dir (struct kw_expansion *exp, void *data)
+static const char *
+expand_dest_dir (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->dpair->dest_dir;
}
-static char *
-expand_source_dir (struct kw_expansion *exp, void *data)
+static const char *
+expand_source_dir (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
return trp->dpair->source_dir;
@@ -365,8 +364,8 @@ format_file_data (struct file_triplet *trp, enum file_type type, char **pret)
return 0;
}
-static char *
-expand_triplet_full (struct kw_expansion *exp, void *data)
+static const char *
+expand_triplet_full (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
char *buf[FILE_TYPE_COUNT] = { NULL, NULL, NULL };
@@ -379,34 +378,32 @@ expand_triplet_full (struct kw_expansion *exp, void *data)
if (format_file_data (trp, file_directive, &buf[file_directive]) == 0)
size += strlen (buf[file_directive]) + 1;
- exp->value = xmalloc (size + 1);
- exp->value[0] = 0;
+ def->value = def->storage = xmalloc (size + 1);
+ def->value[0] = 0;
if (buf[file_dist])
{
- strcat(exp->value, buf[file_dist]);
- strcat(exp->value, "\n");
+ strcat (def->value, buf[file_dist]);
+ strcat (def->value, "\n");
}
if (buf[file_signature])
{
- strcat(exp->value, buf[file_signature]);
- strcat(exp->value, "\n");
+ strcat (def->value, buf[file_signature]);
+ strcat (def->value, "\n");
}
if (buf[file_directive])
{
- strcat(exp->value, buf[file_directive]);
- strcat(exp->value, "\n");
+ strcat (def->value, buf[file_directive]);
+ strcat (def->value, "\n");
}
- exp->value[size-1] = 0; /* Kill terminating newline */
+ def->value[size-1] = 0; /* Kill terminating newline */
free (buf[file_dist]);
free (buf[file_signature]);
free (buf[file_directive]);
-
- exp->static_p = 0;
- return exp->value;
+ return def->value;
}
-static char *
-expand_triplet_upload (struct kw_expansion *exp, void *data)
+static const char *
+expand_triplet_upload (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
char *buf[2] = { NULL, NULL };
@@ -417,56 +414,55 @@ expand_triplet_upload (struct kw_expansion *exp, void *data)
if (format_file_data (trp, file_signature, &buf[file_signature]) == 0)
size += strlen (buf[file_signature]) + 1;
- exp->value = xmalloc (size + 1);
- exp->value[0] = 0;
+ def->value = def->storage = xmalloc (size + 1);
+ def->value[0] = 0;
if (buf[file_dist])
{
- strcat(exp->value, buf[file_dist]);
- strcat(exp->value, "\n");
+ strcat (def->value, buf[file_dist]);
+ strcat (def->value, "\n");
}
if (buf[file_signature])
{
- strcat(exp->value, buf[file_signature]);
- strcat(exp->value, "\n");
+ strcat (def->value, buf[file_signature]);
+ strcat (def->value, "\n");
}
- exp->value[size-1] = 0; /* Kill terminating newline */
+ def->value[size-1] = 0; /* Kill terminating newline */
free (buf[file_dist]);
free (buf[file_signature]);
- exp->static_p = 0;
- return exp->value;
+ return def->value;
}
-static char *
-expand_triplet_dist (struct kw_expansion *exp, void *data)
+static const char *
+expand_triplet_dist (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- format_file_data (trp, file_dist, &exp->value);
- exp->static_p = 0;
- return exp->value;
+ format_file_data (trp, file_dist, &def->storage);
+ def->value = def->storage;
+ return def->value;
}
-static char *
-expand_triplet_sig (struct kw_expansion *exp, void *data)
+static const char *
+expand_triplet_sig (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- format_file_data (trp, file_signature, &exp->value);
- exp->static_p = 0;
- return exp->value;
+ format_file_data (trp, file_signature, &def->storage);
+ def->value = def->storage;
+ return def->value;
}
-static char *
-expand_triplet_directive (struct kw_expansion *exp, void *data)
+static const char *
+expand_triplet_directive (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- format_file_data (trp, file_directive, &exp->value);