ods-enforcer-db-setup.c
Go to the documentation of this file.
/*
* Copyright (c) 2014 Jerry Lundström <lundstrom.jerry@gmail.com>
* Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
* Copyright (c) 2014 OpenDNSSEC AB (svb)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include "daemon/engine.h"
#include "log.h"
#if defined(ENFORCER_DATABASE_SQLITE3)
#include <sqlite3.h>
#include "db/db_schema_sqlite.h"
#include "db/db_data_sqlite.h"
static const char** create = db_schema_sqlite_create;
static const char** drop = db_schema_sqlite_drop;
static const char** data = db_data_sqlite;
static sqlite3* db = NULL;
#elif defined(ENFORCER_DATABASE_MYSQL)
#include <mysql/mysql.h>
#include "db/db_schema_mysql.h"
#include "db/db_data_mysql.h"
static const char** create = db_schema_mysql_create;
static const char** drop = db_schema_mysql_drop;
static const char** data = db_data_mysql;
static MYSQL* db = NULL;
#endif
#define AUTHOR_NAME "Jerry Lundström"
#define COPYRIGHT_STR "Copyright (c) 2014 .SE (The Internet Infrastructure Foundation) OpenDNSSEC"
static void usage(FILE* out) {
fprintf(out,
"\nBSD licensed, see LICENSE in source package for details.\n"
"Version %s. Report bugs to <%s>.\n",
PACKAGE_VERSION,
PACKAGE_BUGREPORT);
fprintf(out, "--help, -h: Print usage.\n");
fprintf(out, "--version, -V: Print version.\n");
fprintf(out, "--force, -f: Yes to all questions.\n");
}
static void version(FILE* out) {
fprintf(out,
"Database setup tool for %s version %s\n"
"Written by %s.\n\n"
"%s. This is free software.\n"
"See source files for more license information\n",
PACKAGE_NAME,
PACKAGE_VERSION,
AUTHOR_NAME,
COPYRIGHT_STR);
exit(0);
}
static int connect_db(engineconfig_type* cfg) {
#if defined(ENFORCER_DATABASE_SQLITE3)
if (!cfg->datastore) {
return -1;
}
if (db) {
return -1;
}
if (sqlite3_initialize() != SQLITE_OK) {
return -1;
}
if (sqlite3_open_v2(cfg->datastore, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_CREATE,
NULL) != SQLITE_OK)
{
return -1;
}
return 0;
#elif defined(ENFORCER_DATABASE_MYSQL)
if (!cfg->datastore) {
return -1;
}
if (db) {
return -1;
}
if (mysql_library_init(0, NULL, NULL)) {
return -1;
}
if (!(db = mysql_init(NULL))
|| !mysql_real_connect(db,
cfg->db_host,
cfg->db_username,
cfg->db_password,
cfg->datastore,
cfg->db_port,
NULL,
0))
{
if (db) {
mysql_close(db);
db = NULL;
}
return -1;
}
return 0;
#else
return -1;
#endif
}
static int disconnect_db() {
#if defined(ENFORCER_DATABASE_SQLITE3)
if (db) {
sqlite3_close(db);
db = NULL;
}
sqlite3_shutdown();
return 0;
#elif defined(ENFORCER_DATABASE_MYSQL)
if (db) {
mysql_close(db);
db = NULL;
}
mysql_library_end();
return 0;
#else
return -1;
#endif
}
static int db_do(const char *sql, size_t size) {
#if defined(ENFORCER_DATABASE_SQLITE3)
sqlite3_stmt* stmt = NULL;
if (!db) {
return -1;
}
if (!sql) {
return -1;
}
if (sqlite3_prepare_v2(db, sql, size, &stmt, NULL) != SQLITE_OK
|| sqlite3_step(stmt) != SQLITE_DONE)
{
if (stmt) {
sqlite3_finalize(stmt);
}
return -1;
}
sqlite3_finalize(stmt);
return 0;
#elif defined(ENFORCER_DATABASE_MYSQL)
if (!db) {
return -1;
}
if (!sql) {
return -1;
}
if (mysql_real_query(db, sql, size)) {
return -1;
}
return 0;
#else
return -1;
#endif
}
static int db_do2(const char** strs) {
char sql[4096];
char *sqlp;
int ret, left, i;
for (i = 0; strs[i]; i++) {
left = sizeof(sql);
sqlp = sql;
for (; strs[i]; i++) {
if ((ret = snprintf(sqlp, left, "%s", strs[i])) >= left) {
return -1;
}
sqlp += ret;
left -= ret;
}
if (db_do(sql, sizeof(sql) - left)) {
return -1;
}
}
return 0;
}
int main(int argc, char* argv[]) {
int c, options_index = 0;
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"force", no_argument, 0, 'f'},
{ 0, 0, 0, 0}
};
int user_certain;
int force = 0;
engineconfig_type* cfg;
const char* cfgfile = ODS_SE_CFGFILE;
ods_log_init("ods-enforcerd", 0, NULL, 0);
while ((c=getopt_long(argc, argv, "hVf",
long_options, &options_index)) != -1) {
switch (c) {
case 'h':
usage(stdout);
exit(0);
case 'V':
version(stdout);
exit(0);
case 'f':
force = 1;
break;
default:
exit(100);
}
}
if (!force) {
printf("*WARNING* This will erase all data in the database; "
"are you sure? [y/N] ");
user_certain = getchar();
if (user_certain != 'y' && user_certain != 'Y') {
printf("Okay, quitting...\n");
return 0;
}
}
cfg = engine_config(cfgfile, 0, NULL);
if (engine_config_check(cfg) != ODS_STATUS_OK) {
engine_config_cleanup(cfg);
fprintf(stderr, "Error: unable to load configuration!\n");
return 1;
}
if (connect_db(cfg)) {
engine_config_cleanup(cfg);
fprintf(stderr, "Error: unable to connect to database!\n");
return 2;
}
/*
* Drop existing schema.
*/
if (db_do2(drop)) {
fprintf(stderr, "Error: unable to drop existing schema!\n");
disconnect_db();
return 3;
}
/*
* Create new schema.
*/
if (db_do2(create)) {
fprintf(stderr, "Error: unable to create schema!\n");
disconnect_db();
return 4;
}
/*
* Insert initial data.
*/
if (db_do2(data)) {
fprintf(stderr, "Error: unable to insert initial data!\n");
disconnect_db();
return 5;
}
engine_config_cleanup(cfg);
printf("Database setup successfully.\n");
return 0;
}
engine_config_cleanup
void engine_config_cleanup(engineconfig_type *config)
Definition: cfg.c:278
db_schema_sqlite_create
const char * db_schema_sqlite_create[]
Definition: db_schema_sqlite.c:29
engineconfig_struct::datastore
const char * datastore
Definition: cfg.h:68
engine.h
engine_config
engineconfig_type * engine_config(const char *cfgfile, int cmdline_verbosity, engineconfig_type *oldcfg)
Definition: cfg.c:59
db_schema_mysql.h
engineconfig_struct::db_host
const char * db_host
Definition: cfg.h:69
engineconfig_struct
Definition: cfg.h:54
engineconfig_struct::db_port
int db_port
Definition: cfg.h:76
db_data_sqlite.h
engineconfig_struct::db_password
const char * db_password
Definition: cfg.h:71
db_data_mysql
const char * db_data_mysql[]
Definition: db_data_mysql.c:29
db_schema_mysql_drop
const char * db_schema_mysql_drop[]
Definition: db_schema_mysql.c:77
main
int main(int argc, char *argv[])
Definition: ods-enforcer-db-setup.c:233
engineconfig_struct::db_username
const char * db_username
Definition: cfg.h:70
db_schema_mysql_create
const char * db_schema_mysql_create[]
Definition: db_schema_mysql.c:29
db_data_sqlite
const char * db_data_sqlite[]
Definition: db_data_sqlite.c:29
COPYRIGHT_STR
#define COPYRIGHT_STR
Definition: ods-enforcer-db-setup.c:62
AUTHOR_NAME
#define AUTHOR_NAME
Definition: ods-enforcer-db-setup.c:61
db_schema_sqlite.h
engine_config_check
ods_status engine_config_check(engineconfig_type *config)
Definition: cfg.c:155
db_data_mysql.h
db_schema_sqlite_drop
const char * db_schema_sqlite_drop[]
Definition: db_schema_sqlite.c:77