/* wydawca - automatic release submission daemon Copyright (C) 2007, 2010 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 . */ #include "wydawca.h" #include "sql.h" #include "builtin.h" struct dictionary_descr { const char *name; int (*init) (struct dictionary *); int (*done) (struct dictionary *); int (*free) (struct dictionary *, void *); void *(*open) (struct dictionary *); int (*close) (struct dictionary *, void *); int (*get) (struct dictionary *, void *, unsigned, unsigned); int (*lookup) (struct dictionary *, void *, const char *); int (*quote) (struct dictionary *, void *, const char *, char **, size_t *); }; static struct dictionary_descr dictionary_tab[] = { { "none", NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { "sql", sql_init_dictionary, sql_done_dictionary, sql_free_result, sql_open, NULL, sql_get_dictionary, sql_lookup_dictionary, sql_quote }, { "builtin", builtin_init, builtin_done, builtin_free_result, builtin_open, NULL, builtin_get, builtin_lookup }, { "external", NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; struct dictionary * dictionary_new (enum dictionary_id id, enum dictionary_type type) { struct dictionary *mp = xmalloc (sizeof mp[0]); memset (mp, 0, sizeof mp[0]); mp->id = id; mp->type = type; return mp; } int dictionary_init (struct dictionary *dict) { struct dictionary_descr *mp = dictionary_tab + dict->type; int rc = 0; if (dict->init_passed++) return 0; if (debug_level > 1) { int i; logmsg (LOG_DEBUG, _("initializing dictionary: %s \"%s\""), mp->name, SP (dict->query)); for (i = 0; i < dict->parmc; i++) logmsg (LOG_DEBUG, " parmv[%d]=%s", i, dict->parmv[i]); } if (mp->init) rc = mp->init (dict); if (rc == 0) dict->init_passed = 1; return rc; } void * dictionary_open (struct dictionary *dict) { struct dictionary_descr *mp = dictionary_tab + dict->type; if (!mp->open) return NULL; return mp->open (dict); } int dictionary_close (struct dictionary *dict, void *handle) { struct dictionary_descr *mp = dictionary_tab + dict->type; if (!mp->close) return 0; return mp->close (dict, handle); } int dictionary_done (struct dictionary *dict) { struct dictionary_descr *mp = dictionary_tab + dict->type; int rc = 0; if (dict->init_passed == 0) return 0; if (--dict->init_passed) return 0; if (debug_level > 1) { int i; logmsg (LOG_DEBUG, _("closing dictionary: %s \"%s\""), mp->name, SP (dict->query)); for (i = 0; i < dict->parmc; i++) logmsg (LOG_DEBUG, " parmv[%d]=%s", i, dict->parmv[i]); } if (mp->done) rc = mp->done (dict); free (dict->result); dict->result = NULL; dict->result_size = 0; return rc; } int dictionary_lookup (struct dictionary *dict, void *handle, const char *cmd) { struct dictionary_descr *mp = dictionary_tab + dict->type; if (debug_level > 1) { if (cmd) logmsg (LOG_DEBUG, _("dictionary lookup: %s \"%s\""), mp->name, cmd); else logmsg (LOG_DEBUG, _("dictionary lookup: %s"), mp->name); } if (!dict->init_passed) { logmsg (LOG_CRIT, _("INTERNAL ERROR: dictionary %s \"%s\" not initialized"), mp->name, SP (dict->query)); return 1; } if (!mp->lookup) { logmsg (LOG_CRIT, _("INTERNAL ERROR: no lookup function for dictionary %s \"%s\""), mp->name, SP (dict->query)); return 1; } if (mp->free) mp->free (dict, handle); return mp->lookup (dict, handle, cmd); } unsigned dictionary_num_rows (struct dictionary *dict) { return dict->nrow; } unsigned dictionary_num_cols (struct dictionary *dict) { return dict->ncol; } const char * dictionary_result (struct dictionary *dict, void *handle, unsigned nrow, unsigned ncol) { struct dictionary_descr *mp = dictionary_tab + dict->type; if (nrow >= dict->nrow || ncol >= dict->ncol || mp->get (dict, handle, nrow, ncol)) return NULL; return dict->result; } void dictionary_copy_result (struct dictionary *dict, const char *res, size_t size) { if (dict->result_size < size + 1) { dict->result_size = size + 1; dict->result = x2realloc (dict->result, &dict->result_size); } memcpy (dict->result, res, size); dict->result[size] = 0; } /* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed quoted string. Return its length. */ int dictionary_quote_string (struct dictionary *dict, void *handle, const char *input, char **poutput, size_t *psize) { struct dictionary_descr *mp = dictionary_tab + dict->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 (dict, handle, input, poutput, psize); size = wordsplit_c_quoted_length (input, 0, "e); output = xmalloc (size + 1); wordsplit_c_quote_copy (output, input, 0); output[size] = 0; *poutput = output; if (psize) *psize = size; return 0; }