--- plugins/sql.c.orig Fri Jan 9 00:30:26 2004 +++ plugins/sql.c Wed Mar 24 01:21:13 2004 @@ -332,6 +332,126 @@ static void _pgsql_close(void *conn) } #endif /* HAVE_PGSQL */ +#ifdef HAVE_SQLITE +#include + +static void *_sqlite_open(char *host, char *port, int usessl, + const char *user, const char *password, + const char *database, const sasl_utils_t *utils) +{ + int rc; + sqlite *db; + char *zErrMsg = NULL; + + db = sqlite_open(database, 0, &zErrMsg); + if (db == NULL) { + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg); + return NULL; + } + + rc = sqlite_exec(db, "PRAGMA empty_result_callbacks = ON", NULL, NULL, &zErrMsg); + if (rc != SQLITE_OK) { + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg); + sqlite_close(db); + return NULL; + } + + return (void*)db; +} + +static int _sqlite_escape_str(char *to, const char *from) +{ + char s; + + while ( (s = *from++) != '\0' ) { + if (s == '\'' || s == '\\') { + *to++ = '\\'; + } + *to++ = s; + } + *to = '\0'; + + return 0; +} + +static int sqlite_my_callback(void *pArg, int argc, char **argv, + char **columnNames) +{ + char **result = (char**)pArg; + + if (argv == NULL) { + *result = NULL; /* no record */ + } else if (argv[0] == NULL) { + *result = strdup(SQL_NULL_VALUE); /* NULL IS SQL_NULL_VALUE */ + } else { + *result = strdup(argv[0]); + } + + return /*ABORT*/1; +} + +static int _sqlite_exec(void *db, const char *cmd, char *value, size_t size, + size_t *value_len, const sasl_utils_t *utils) +{ + int rc; + char *result = NULL; + char *zErrMsg = NULL; + + rc = sqlite_exec((sqlite*)db, cmd, sqlite_my_callback, (void*)&result, &zErrMsg); + if (rc != SQLITE_OK && rc != SQLITE_ABORT) { + utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s ", zErrMsg); + return -1; + } + + if (rc == SQLITE_OK) { + /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */ + return 0; + } + + if (result == NULL) { + /* umm nothing found */ + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + return -1; + } + + /* XXX: Duplication cannot be found by this method. */ + + /* now get the result set value and value_len */ + /* we only fetch one because we don't care about the rest */ + if (value) { + strncpy(value, result, size - 2); + value[size - 1] = '\0'; + if (value_len) { + *value_len = strlen(value); + } + } + + /* free result */ + free(result); + return 0; +} + +static int _sqlite_begin_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite_exec(db, "BEGIN TRANSACTION", NULL, 0, NULL, utils); +} + +static int _sqlite_commit_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite_exec(db, "COMMIT TRANSACTION", NULL, 0, NULL, utils); +} + +static int _sqlite_rollback_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, 0, NULL, utils); +} + +static void _sqlite_close(void *db) +{ + sqlite_close((sqlite*)db); +} +#endif /* HAVE_SQLITE */ + static const sql_engine_t sql_engines[] = { #ifdef HAVE_MYSQL { "mysql", &_mysql_open, &_mysql_escape_str, @@ -342,6 +462,11 @@ static const sql_engine_t sql_engines[] { "pgsql", &_pgsql_open, &_pgsql_escape_str, &_pgsql_begin_txn, &_pgsql_commit_txn, &_pgsql_rollback_txn, &_pgsql_exec, &_pgsql_close }, +#endif +#ifdef HAVE_SQLITE + { "sqlite", &_sqlite_open, &_sqlite_escape_str, + &_sqlite_begin_txn, &_sqlite_commit_txn, &_sqlite_rollback_txn, + &_sqlite_exec, &_sqlite_close }, #endif { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };