aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-02-17 18:36:54 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-02-17 18:36:54 +0200
commit317095181674a01651602ddf6817e888d0ad5280 (patch)
treeda9a84a50223918408dfb578813c6fb098c1870c
parent3277cd4abfa20e8b2499f052a6eb3792d8aa6cce (diff)
downloadwydawca-317095181674a01651602ddf6817e888d0ad5280.tar.gz
wydawca-317095181674a01651602ddf6817e888d0ad5280.tar.bz2
Begin rewriting method system
* src/builtin.c, src/builtin.h: New files. * src/Makefile.am (wydawca_SOURCES): Add builtin.c and builtin.h * src/config.c: New keyword access-method.query * src/update-2.0.awk: Update. * src/meta.c: Remove quote_string (replaced by method_quote_string). (meta_escape): Add `handle' argument. * src/method.c (struct method_descr): New methods: open, close, quote. Updated methods: free, run, get. All callers updated. (method_quote_string): New function. * src/process.c (scan_directory_pair): Init all access methods at once. * src/sql.c: Take name of the SQL connection from method->parmv[0]. Adapt to changes to the method subsystem. * src/sql.h: Likewise. * src/wydawca.h (struct access_method): New members id, parmc, parmv, storage. Remove union v. (meta_escape): Take 3 arguments. (method_new): Take 2 arguments. (method_open, method_close, method_quote_string): New proto. (method_run, method_result): Change signature. * src/mail.c, src/triplet.c, src/verify.c * etc/wydawca.rc: Update.
-rw-r--r--etc/wydawca.rc16
-rw-r--r--src/Makefile.am2
-rw-r--r--src/builtin.c56
-rw-r--r--src/builtin.h21
-rw-r--r--src/config.c68
-rw-r--r--src/mail.c20
-rw-r--r--src/meta.c43
-rw-r--r--src/method.c124
-rw-r--r--src/process.c18
-rw-r--r--src/sql.c55
-rw-r--r--src/sql.h13
-rw-r--r--src/triplet.c20
-rw-r--r--src/update-2.0.awk12
-rw-r--r--src/verify.c36
-rw-r--r--src/wydawca.h56
15 files changed, 377 insertions, 183 deletions
diff --git a/etc/wydawca.rc b/etc/wydawca.rc
index 205c4e0..5a21376 100644
--- a/etc/wydawca.rc
+++ b/etc/wydawca.rc
@@ -53,8 +53,8 @@ sql default {
access-method project-owner {
type sql;
- params (default,
- "SELECT user.email, user.realname "
+ params (default);
+ query "SELECT user.email, user.realname "
"FROM user,user_group,groups "
"WHERE user_group.user_id=user.user_id "
"AND user_group.group_id=groups.group_id "
@@ -64,14 +64,14 @@ access-method project-owner {
access-method user-data {
type sql;
- params (default,
- "SELECT email, realname FROM user WHERE user_name='${user}'");
+ params (default);
+ query "SELECT email, realname FROM user WHERE user_name='${user}'");
}
access-method verify-user {
type sql;
- params (default,
- "SELECT user.user_name "
+ params (default);
+ query "SELECT user.user_name "
"FROM user,user_group, groups "
"WHERE user_group.user_id=user.user_id "
"AND user_group.group_id=groups.group_id "
@@ -81,8 +81,8 @@ access-method verify-user {
access-method gpg-key {
type sql;
- params (default,
- "SELECT gpg_key FROM user WHERE user_name='$u'");
+ params (default);
+ query "SELECT gpg_key FROM user WHERE user_name='$u'");
}
#############################################################################
diff --git a/src/Makefile.am b/src/Makefile.am
index 67e21e0..b5e5040 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,6 +16,8 @@
sbin_PROGRAMS=wydawca
wydawca_SOURCES=\
+ builtin.c\
+ builtin.h\
cmdline.h\
config.c\
directive.c\
diff --git a/src/builtin.c b/src/builtin.c
new file mode 100644
index 0000000..9786383
--- /dev/null
+++ b/src/builtin.c
@@ -0,0 +1,56 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 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 "builtin.h"
+
+int
+builtin_init (struct access_method *meth)
+{
+ return 0;
+}
+
+int
+builtin_done (struct access_method *meth)
+{
+ return 0;
+}
+
+void *
+builtin_open (struct access_method *meth)
+{
+ return meth;
+}
+
+int
+builtin_run (struct access_method *meth, void *handle, const char *req)
+{
+ meth->nrow = meth->parmc;
+ meth->ncol = 1;
+ return 0;
+}
+
+int
+builtin_get (struct access_method *method, void *handle,
+ unsigned nrow, unsigned ncol)
+{
+ if (nrow >= method->parmc)
+ return 1;
+ method_copy_result (method, method->parmv[nrow],
+ strlen (method->parmv[nrow]));
+ return 0;
+}
+
diff --git a/src/builtin.h b/src/builtin.h
new file mode 100644
index 0000000..4fe40bd
--- /dev/null
+++ b/src/builtin.h
@@ -0,0 +1,21 @@
+/* wydawca - automatic release submission daemon
+ Copyright (C) 2009 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/>. */
+
+int builtin_init (struct access_method *);
+int builtin_done (struct access_method *);
+void *builtin_open (struct access_method *);
+int builtin_get (struct access_method *, void *, unsigned, unsigned);
+int builtin_run (struct access_method *meth, void *, const char *req);
diff --git a/src/config.c b/src/config.c
index 32b54dd..6b3c89a 100644
--- a/src/config.c
+++ b/src/config.c
@@ -946,7 +946,7 @@ cb_access_method_params (enum gconf_callback_command cmd,
gconf_value_t *value,
void *cb_data)
{
- char **param = varptr;
+ struct access_method *meth = varptr;
size_t size;
if (cmd != gconf_callback_set_value)
@@ -962,23 +962,29 @@ cb_access_method_params (enum gconf_callback_command cmd,
size = gl_list_size (value->v.list);
if (size == 0)
- param[0] = param[1] = NULL;
+ {
+ meth->parmc = 0;
+ meth->parmv = NULL;
+ }
else
{
- const gconf_value_t *vp = gl_list_get_at (value->v.list, 0);
+ int i;
+ const void *p;
+ gl_list_iterator_t itr = gl_list_iterator (value->v.list);
+
+ meth->parmc = size;
+ meth->parmv = xcalloc (size + 1, sizeof (meth->parmv[0]));
- if (assert_string_arg (locus, cmd, vp))
- return 1;
- param[0] = xstrdup (vp->v.string);
- if (size > 1)
+ for (i = 0; gl_list_iterator_next (&itr, &p, NULL); i++)
{
- vp = gl_list_get_at (value->v.list, 1);
+ const gconf_value_t *vp = p;
+
if (assert_string_arg (locus, cmd, vp))
- return 1;
- param[1] = xstrdup (vp->v.string);
- if (size > 2)
- gconf_warning (locus, 0, _("excess list elements ignored"));
+ break;
+
+ meth->parmv[i] = xstrdup (vp->v.string);
}
+ meth->parmv[i] = NULL;
}
return 0;
}
@@ -987,8 +993,10 @@ static struct gconf_keyword access_method_kw[] = {
{ "type", N_("type"), N_("Method type"),
gconf_type_string, NULL, offsetof(struct access_method, type),
cb_access_method_type },
+ { "query", N_("string"), N_("Query template"),
+ gconf_type_string, NULL, offsetof(struct access_method, query) },
{ "params", N_("arg"), N_("Set method parameters"),
- gconf_type_string|GCONF_LIST, NULL, offsetof(struct access_method, param),
+ gconf_type_string|GCONF_LIST, NULL, 0,
cb_access_method_params },
{ NULL }
};
@@ -1042,7 +1050,7 @@ cb_access_method (enum gconf_callback_command cmd,
if (string_to_access_method_id (locus, value->v.string, &id))
return 1;
pmeth = (struct access_method **) varptr + id;
- *pmeth = method_new (method_builtin);
+ *pmeth = method_new (id, method_builtin);
*pdata = *pmeth;
break;
@@ -1051,15 +1059,15 @@ cb_access_method (enum gconf_callback_command cmd,
switch (meth->type)
{
case method_sql:
- if (!meth->param[0])
+ if (meth->parmc == 0 || !meth->parmv[0])
{
gconf_error (locus, 0, _("SQL connection is not declared"));
meth->type = method_none;
}
- else if (!sql_connection_exists_p (meth->param[0]))
+ else if (!sql_connection_exists_p (meth->parmv[0]))
{
gconf_error (locus, 0, _("SQL connection `%s' not declared"),
- meth->param[0]);
+ meth->parmv[0]);
meth->type = method_none;
}
break;
@@ -1149,18 +1157,12 @@ cb_directory (enum gconf_callback_command cmd,
else if (dpair->access_method[verify_method]->type != method_none
&& dpair->access_method[gpg_key_method]->type != method_none)
{
- /* FIXME: only sql supported so far */
- if (dpair->access_method[verify_method]->type == method_builtin
- && dpair->access_method[gpg_key_method]->type
- != method_builtin)
- gconf_error (locus, 0,
- _("Sorry, method `builtin' is not yet supported"));
- else if (dpair->access_method[verify_method]->type
- == method_external
- && dpair->access_method[gpg_key_method]->type
- != method_external)
- gconf_error (locus, 0,
- _("Sorry, method `external' is not yet supported"));
+ int i;
+
+ for (i = 0; i < access_method_count; i++)
+ if (dpair->access_method[i]->type == method_external)
+ gconf_error (locus, 0,
+ _("Sorry, method type `external' is not yet supported"));
}
register_directory_pair (dpair);
@@ -1243,14 +1245,14 @@ config_help ()
void
config_init()
{
+ int i;
+
gconf_set_keywords (wydawca_kw);
gconf_include_path_setup (DEFAULT_VERSION_INCLUDE_DIR,
DEFAULT_INCLUDE_DIR, NULL);
gconf_preprocessor = DEFAULT_PREPROCESSOR;
gconf_log_to_stderr = true;
- default_access_method[verify_method] = method_new (method_builtin);
- default_access_method[gpg_key_method] = method_new (method_builtin);
- default_access_method[project_owner_method] = method_new (method_none);
- default_access_method[user_data_method] = method_new (method_none);
+ for (i = 0; i < access_method_count; i++)
+ default_access_method[i] = method_new (i, method_builtin);
}
diff --git a/src/mail.c b/src/mail.c
index 619fba4..6b76f43 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -269,29 +269,32 @@ get_recipient (struct access_method *method, struct file_triplet *trp,
mu_address_t rcpt = NULL;
char *text;
int rc;
-
+ void *md;
+
if (method->type == method_none)
{
*errp = "access method is not configured";
return NULL;
}
- if (method_init (method))
+ md = method_open (method);
+ if (!md)
{
- *errp = "failed to initialize access method";
+ *errp = "failed to open access method";
return NULL;
}
make_default_meta (def, trp->user, trp->project);
- meta_escape (method, def);
- text = meta_expand_string (method->param[1], def, NULL);
+ meta_escape (method, md, def);
+ text = meta_expand_string (method->query, def, NULL);
meta_free (def);
- rc = method_run (method, text);
+ rc = method_run (method, md, text);
free (text);
if (rc)
{
*errp = "cannot obtain recipient emails";
+ method_close (method, md);
return NULL;
}
@@ -307,18 +310,19 @@ get_recipient (struct access_method *method, struct file_triplet *trp,
for (i = 0; i < nrows; i++)
{
mu_address_t addr;
- const char *str = method_result (method, i, 0);
+ const char *str = method_result (method, md, i, 0);
if (mu_address_create (&addr, str))
continue;
if (ncols > 0)
{
- str = method_result (method, i, 1);
+ str = method_result (method, md, i, 1);
if (str)
mu_address_set_personal (addr, 1, str);
}
mu_address_union (&rcpt, addr);
mu_address_destroy (&addr);
}
+ method_close (method, md);
return rcpt;
}
diff --git a/src/meta.c b/src/meta.c
index 4516df2..eb51a78 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -115,52 +115,17 @@ meta_expand_string (const char *string, struct metadef *def, void *data)
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)
+meta_escape (struct access_method *method, void *handle, struct metadef *def)
{
for (; def->kw; def++)
{
if (def->value)
{
char *newval;
- quote_string (method, def->value, &newval);
+
+ /* FIXME: Return value? */
+ method_quote_string (method, handle, def->value, &newval, NULL);
if (def->storage)
free (def->storage);
def->value = def->storage = newval;
diff --git a/src/method.c b/src/method.c
index 3ef9d6d..a201f02 100644
--- a/src/method.c
+++ b/src/method.c
@@ -16,31 +16,41 @@
#include "wydawca.h"
#include "sql.h"
+#include "builtin.h"
struct method_descr
{
const char *name;
+
int (*init) (struct access_method *);
int (*done) (struct access_method *);
- int (*free) (struct access_method *);
- int (*get) (struct access_method *method, unsigned nrow, unsigned ncol);
+ int (*free) (struct access_method *, void *);
+
+ void *(*open) (struct access_method *);
+ int (*close) (struct access_method *, void *);
- int (*run) (struct access_method *, const char *);
+ int (*get) (struct access_method *, void *, unsigned, unsigned);
+ int (*run) (struct access_method *, void *, const char *);
+ int (*quote) (struct access_method *, void *, const char *, char **, size_t *);
};
static struct method_descr method_tab[] = {
- { "none", NULL, NULL, NULL, NULL, NULL },
+ { "none", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
{ "sql", sql_init_method, sql_done_method, sql_free_result,
- sql_get_method, sql_run_method },
- { "builtin", NULL, NULL, NULL, NULL, NULL },
- { "external", NULL, NULL, NULL, NULL, NULL }
+ sql_open, NULL, sql_get_method, sql_run_method, sql_quote },
+ { "builtin", builtin_init, builtin_done, NULL,
+ builtin_open, NULL,
+ builtin_get,
+ builtin_run },
+ { "external", NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
struct access_method *
-method_new (enum access_method_type type)
+method_new (enum access_method_id id, enum access_method_type type)
{
struct access_method *mp = xmalloc (sizeof mp[0]);
memset (mp, 0, sizeof mp[0]);
+ mp->id = id;
mp->type = type;
return mp;
}
@@ -54,9 +64,13 @@ method_init (struct access_method *method)
if (method->init_passed++)
return 0;
if (debug_level > 1)
- logmsg (LOG_DEBUG, "Initializing method: %s \"%s\" \"%s\"",
- mp->name, method->param[0],
- method->param[1] ? method->param[1] : "");
+ {
+ int i;
+ logmsg (LOG_DEBUG, "Initializing method: %s \"%s\"",
+ mp->name, SP (method->query));
+ for (i = 0; i < method->parmc; i++)
+ logmsg (LOG_DEBUG, " parmv[%d]=%s", i, method->parmv[i]);
+ }
if (mp->init)
rc = mp->init (method);
if (rc == 0)
@@ -64,6 +78,25 @@ method_init (struct access_method *method)
return rc;
}
+void *
+method_open (struct access_method *method)
+{
+ struct method_descr *mp = method_tab + method->type;
+
+ if (!mp->open)
+ return NULL;
+ return mp->open (method);
+}
+
+int
+method_close (struct access_method *method, void *handle)
+{
+ struct method_descr *mp = method_tab + method->type;
+ if (!mp->close)
+ return 0;
+ return mp->close (method, handle);
+}
+
int
method_done (struct access_method *method)
{
@@ -75,9 +108,13 @@ method_done (struct access_method *method)
if (--method->init_passed)
return 0;
if (debug_level > 1)
- logmsg (LOG_DEBUG, "Closing method: %s \"%s\" \"%s\"",
- mp->name, method->param[0],
- method->param[1] ? method->param[1] : "");
+ {
+ int i;
+ logmsg (LOG_DEBUG, "Closing method: %s \"%s\"",
+ mp->name, SP (method->query));
+ for (i = 0; i < method->parmc; i++)
+ logmsg (LOG_DEBUG, " parmv[%d]=%s", i, method->parmv[i]);
+ }
if (mp->done)
rc = mp->done (method);
free (method->result);
@@ -87,33 +124,33 @@ method_done (struct access_method *method)
}
int
-method_run (struct access_method *method, const char *cmd)
+method_run (struct access_method *method, void *handle, const char *cmd)
{
struct method_descr *mp = method_tab + method->type;
- if (!cmd)
+ if (debug_level > 1)
{
- logmsg (LOG_CRIT, "No command specified for method %s", mp->name);
- return 1;
+ if (cmd)
+ logmsg (LOG_DEBUG, "Running method: %s \"%s\"", mp->name, cmd);
+ else
+ logmsg (LOG_DEBUG, "Running method: %s", mp->name);
}
- if (debug_level > 1)
- logmsg (LOG_DEBUG, "Running method: %s \"%s\"", mp->name, cmd);
if (!method->init_passed)
{
logmsg (LOG_CRIT, "INTERNAL ERROR: Method %s \"%s\" not initialized",
- mp->name, method->param[0]);
+ mp->name, SP (method->query));
return 1;
}
if (!mp->run)
{
logmsg (LOG_CRIT, "INTERNAL ERROR: No run function for method %s \"%s\"",
- mp->name, method->param[0]);
+ mp->name, SP (method->query));
return 1;
}
if (mp->free)
- mp->free (method);
- return mp->run (method, cmd);
+ mp->free (method, handle);
+ return mp->run (method, handle, cmd);
}
unsigned
@@ -129,12 +166,13 @@ method_num_cols (struct access_method *method)
}
const char *
-method_result (struct access_method *method, unsigned nrow, unsigned ncol)
+method_result (struct access_method *method, void *handle,
+ unsigned nrow, unsigned ncol)
{
struct method_descr *mp = method_tab + method->type;
if (nrow >= method->nrow || ncol >= method->ncol
- || mp->get (method, nrow, ncol))
+ || mp->get (method, handle, nrow, ncol))
return NULL;
return method->result;
}
@@ -150,3 +188,37 @@ method_copy_result (struct access_method *method, const char *res, size_t size)
memcpy (method->result, res, size);
method->result[size] = 0;
}
+
+/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed
+ quoted string. Return its length. */
+int
+method_quote_string (struct access_method *method, void *handle,
+ const char *input,
+ char **poutput, size_t *psize)
+{
+ struct method_descr *mp = method_tab + method->type;
+ size_t size;
+ int quote;
+ char *output;
+
+ if (!input)
+ {
+ *poutput = xmalloc (1);
+ (*poutput)[0] = 0;
+ *psize = 1;
+ return 0;
+ }
+
+ if (mp->quote)
+ return mp->quote (method, handle, input, poutput, psize);
+
+ size = argcv_quoted_length (input, &quote);
+ output = xmalloc (size);
+ argcv_quote_copy (output, input);
+
+ *poutput = output;
+ if (psize)
+ *psize = size;
+ return 0;
+}
+
diff --git a/src/process.c b/src/process.c
index 583a055..dbde217 100644
--- a/src/process.c
+++ b/src/process.c
@@ -165,10 +165,20 @@ scan_directory_pair (struct directory_pair *dpair)
closedir (dir);
- if (count_collected_triplets () > 0
- && method_init (dpair->access_method[verify_method]) == 0
- && method_init (dpair->access_method[gpg_key_method]) == 0)
- enumerate_triplets (dpair);
+ if (count_collected_triplets () > 0)
+ {
+ int i;
+
+ for (i = 0; i < access_method_count; i++)
+ {
+ if (method_init (dpair->access_method[i]))
+ {
+ logmsg (LOG_ERR, "failed to initialize access method %d", i);
+ return;
+ }
+ }
+ enumerate_triplets (dpair);
+ }
}
static void
diff --git a/src/sql.c b/src/sql.c
index f74b25b..1142b17 100644
--- a/src/sql.c
+++ b/src/sql.c
@@ -58,12 +58,12 @@ sql_connection_exists_p (const char *ident)
int
sql_init_method (struct access_method *method)
{
- struct sqlconn *conn = sql_find_connection (method->param[0]);
+ struct sqlconn *conn = sql_find_connection (method->parmv[0]);
if (!conn)
{
logmsg (LOG_EMERG, "INTERNAL ERROR: cannot find SQL connection %s",
- method->param[0]);
+ method->parmv[0]);
abort ();
}
@@ -75,18 +75,24 @@ sql_init_method (struct access_method *method)
conn->socket, 0))
{
logmsg (LOG_ERR, "Failed to connect to database %s: Error: %s\n",
- method->param[0], mysql_error (&conn->mysql));
+ method->parmv[0], mysql_error (&conn->mysql));
return 1;
}
}
- method->v.sqlconn = conn;
+ method->storage = conn;
return 0;
}
+void *
+sql_open (struct access_method *method)
+{
+ return method->storage;
+}
+
int
-sql_free_result (struct access_method *method)
+sql_free_result (struct access_method *method, void *handle)
{
- struct sqlconn *conn = method->v.sqlconn;
+ struct sqlconn *conn = handle;
if (conn->result)
{
mysql_free_result (conn->result);
@@ -99,22 +105,29 @@ sql_free_result (struct access_method *method)
int
sql_done_method (struct access_method *method)
{
- struct sqlconn *conn = method->v.sqlconn;
+ struct sqlconn *conn = method->storage;
if (!conn || conn->initcount == 0)
return 0;
if (--conn->initcount)
return 0;
- sql_free_result (method);
+ sql_free_result (method, conn); /* FIXME: Not needed */
mysql_close (&conn->mysql);
+ method->storage = NULL;
return 0;
}
/* Execute QUERY using the given access METHOD. Return 0 on success. */
int
-sql_run_method (struct access_method *method, const char *query)
+sql_run_method (struct access_method *method, void *handle, const char *query)
{
- struct sqlconn *conn = method->v.sqlconn;
+ struct sqlconn *conn = handle;
MYSQL *mysql = &conn->mysql;
+
+ if (!query)
+ {
+ logmsg (LOG_ERR, "No query supplied for method %s", "sql");
+ return 1;
+ }
if (mysql_query (mysql, query))
{
@@ -144,9 +157,10 @@ sql_run_method (struct access_method *method, const char *query)
}
int
-sql_get_method (struct access_method *method, unsigned nrow, unsigned ncol)
+sql_get_method (struct access_method *method, void *handle,
+ unsigned nrow, unsigned ncol)
{
- struct sqlconn *conn = method->v.sqlconn;
+ struct sqlconn *conn = handle;
MYSQL_ROW row;
size_t len;
@@ -163,3 +177,20 @@ sql_get_method (struct access_method *method, unsigned nrow, unsigned ncol)
return 0;
}
+int
+sql_quote (struct access_method *method, void *handle, const char *input,
+ char **poutput, size_t *psize)
+{
+ struct sqlconn *conn = handle;
+ size_t len, size;
+ char *output;
+
+ len = strlen (input);
+ size = 2 * len + 1;
+ output = xmalloc (size);
+ mysql_real_escape_string (&conn->mysql, output, input, len);
+ *poutput = output;
+ if (psize)
+ *psize = strlen (output);
+ return 0;
+}
diff --git a/src/sql.h b/src/sql.h
index 4529ce9..d581e57 100644
--- a/src/sql.h
+++ b/src/sql.h
@@ -1,5 +1,5 @@
/* wydawca - automatic release submission daemon
- Copyright (C) 2007 Sergey Poznyakoff
+ Copyright (C) 2009 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
@@ -36,6 +36,11 @@ struct sqlconn *sql_find_connection (const char *ident);
int sql_init_method (struct access_method *method);
int sql_done_method (struct access_method *method);
-int sql_run_method (struct access_method *method, const char *cmd);
-int sql_get_method (struct access_method *method, unsigned nrow, unsigned ncol);
-int sql_free_result (struct access_method *method);
+void *sql_open (struct access_method *method);
+
+int sql_run_method (struct access_method *method, void *handle,
+ const char *cmd);
+int sql_get_method (struct access_method *method, void *handle,
+ unsigned nrow, unsigned ncol);
+int sql_free_result (struct access_method *method, void *handle);
+int sql_quote (struct access_method *, void *, const char *, char **, size_t *);
diff --git a/src/triplet.c b/src/triplet.c
index 2fafc8f..363ba0f 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -89,8 +89,6 @@ register_file (struct file_info *finfo)
ret->file[finfo->type] = *finfo;
}
-#define SP(s) ((s) ? (s) : "NONE")
-
/* Return true if any part of the triplet TRP was modified more than
TTL seconds ago */
static bool
@@ -477,6 +475,7 @@ fill_user_data (struct file_triplet *trp)
unsigned nrows, ncols;
struct metadef def[5];
struct passwd *pw;
+ void *md;
if (trp->user_data)
return;
@@ -484,21 +483,25 @@ fill_user_data (struct file_triplet *trp)
if (method->type == method_none)
return;
- if (method_init (method))
+ md = method_open (method);
+ if (md)
return;
pw = getpwuid (TRIPLET_UID (trp));
if (!pw)
return;
make_default_meta (def, pw->pw_name, trp->project);
- meta_escape (method, def);
- text = meta_expand_string (method->param[1], def, NULL);
+ meta_escape (method, md, def);
+ text = meta_expand_string (method->query, def, NULL);
meta_free (def);
- rc = method_run (method, text);
+ rc = method_run (method, md, text);
free (text);
if (rc)
- return;
+ {
+ method_close (method, md);
+ return;
+ }
nrows = method_num_rows (method);
ncols = method_num_cols (method);
@@ -509,11 +512,12 @@ fill_user_data (struct file_triplet *trp)
trp->user_data = xcalloc (ncols, sizeof (trp->user_data[0]));
for (i = 0; i < ncols; i++)
{
- const char *str = method_result (method, 0, i);
+ const char *str = method_result (method, md, 0, i);
if (str)
trp->user_data[i] = xstrdup (str);
}
}
+ method_close (method, md);
}
static const char *
diff --git a/src/update-2.0.awk b/src/update-2.0.awk
index 16cbc15..3a25244 100644
--- a/src/update-2.0.awk
+++ b/src/update-2.0.awk
@@ -107,18 +107,16 @@ $1 == "project-owner" || $1 == "user-data" || $1 == "verify-user" ||
indent(len + 2)
printf("type %s;\n", $2)
if (NF > 2) {
- indent(len + 2)
- printf("params (");
- printf("\"%s\"", $3)
if (NF > 3) {
- printf(",\n");
- indent(len + 10)
- printf("\"")
+ indent(len + 2)
+ printf("query \"");
for (i = 4; i < NF; i++)
printf("%s ", $i)
printf("%s\"", $NF)
+ print ";"
}
- print ");"
+ indent(len + 2)
+ printf("params (%s);\n", $3)
}
indent(len)
print("}")
diff --git a/src/verify.c b/src/verify.c
index cd0cb3f..9061532 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -100,6 +100,7 @@ check_access_rights (struct file_triplet *trp, struct directory_pair *dpair,
char *command;
const char *result;
struct metadef def[5];
+ void *md;
if (fill_project_name (trp))
return 1;
@@ -108,14 +109,19 @@ check_access_rights (struct file_triplet *trp, struct directory_pair *dpair,
logmsg (LOG_DEBUG, "verifying access rights for user %s to project %s",
user, trp->project);
+ md = method_open (method);
+ if (!md)
+ return 1;
+
make_default_meta (def, user, trp->project);
- meta_escape (method, def);
- command = meta_expand_string (method->param[1], def, NULL);
+ meta_escape (method, md, def);
+ command = meta_expand_string (method->query, def, NULL);
meta_free (def);
- rc = method_run (method, command);
+ rc = method_run (method, md, command);
free (command);
+ method_close (method, md);
if (rc)
{
logmsg (LOG_ERR, "Cannot verify access rights for %s on %s",
@@ -123,7 +129,7 @@ check_access_rights (struct file_triplet *trp, struct directory_pair *dpair,
return 1;
}
- result = method_result (method, 0, 0);
+ result = method_result (method, md, 0, 0);
if (!result || strcmp (result, user))
{
UPDATE_STATS (STAT_ACCESS_VIOLATIONS);
@@ -145,37 +151,44 @@ verify_directive_file (struct file_triplet *trp, struct directory_pair *dpair)
const char *pubkey;
int rc;
struct metadef def[5];
-
+ void *md;
+
if (!trp->file[file_directive].name)
return 1;
+ md = method_open (method);
+ if (!md)
+ return 1;
pw = getpwuid (TRIPLET_UID (trp));
if (!pw)
{
logmsg (LOG_ERR, "%s: getpwuid failed: %s",
trp->name, strerror (errno));
+ method_close (method, md);
return 1;
}
trp->gid = pw->pw_gid;
trp->user = xstrdup (pw->pw_name);
make_default_meta (def, trp->user, NULL);
- meta_escape (method, def);
- command = meta_expand_string (method->param[1], def, NULL);
+ meta_escape (method, md, def);
+ command = meta_expand_string (method->query, def, NULL);
meta_free (def);
- rc = method_run (method, command);
+ rc = method_run (method, md, command);
free (command);
if (rc)
{
logmsg (LOG_ERR, "Cannot get PGP key for %s", trp->user);
+ method_close (method, md);
return 1;
}
- pubkey = method_result (method, 0, 0);
+ pubkey = method_result (method, md, 0, 0);
if (!pubkey || pubkey[0] == 0)
{
logmsg (LOG_ERR, "No GPG key for %s", trp->user);
+ method_close (method, md);
return 1;
}
@@ -186,11 +199,14 @@ verify_directive_file (struct file_triplet *trp, struct directory_pair *dpair)
{
/*FIXME: Update stats */
logmsg (LOG_ERR, "invalid signature for %s", trp->name);
+ method_close (method, md);
return 1;
}
else if (debug_level)
logmsg (LOG_DEBUG, "%s: directive file signature OK", trp->name);