diff options
author | Kevin McCarthy <kevin@8t8.us> | 2019-07-06 14:01:13 -0700 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2019-08-03 14:08:09 -0700 |
commit | be89dc7b3c3af202cfb770550fdf0083ee6ac253 (patch) | |
tree | d75bb9a3eb293222fcb1251640c0088b2541fba0 /autocrypt | |
parent | e966890252fac950a53189b6b928bfa4cd35e93c (diff) |
Add database and schema initialization.
Add mutt_mkdir() library function supporting recursive mkdir.
Diffstat (limited to 'autocrypt')
-rw-r--r-- | autocrypt/Makefile.am | 3 | ||||
-rw-r--r-- | autocrypt/autocrypt.c | 57 | ||||
-rw-r--r-- | autocrypt/autocrypt.h | 6 | ||||
-rw-r--r-- | autocrypt/autocrypt_db.c | 94 | ||||
-rw-r--r-- | autocrypt/autocrypt_private.h | 29 | ||||
-rw-r--r-- | autocrypt/autocrypt_schema.c | 129 |
6 files changed, 315 insertions, 3 deletions
diff --git a/autocrypt/Makefile.am b/autocrypt/Makefile.am index 235c43c2..a874a3d1 100644 --- a/autocrypt/Makefile.am +++ b/autocrypt/Makefile.am @@ -7,4 +7,5 @@ AM_CPPFLAGS = -I$(top_srcdir) -I../intl noinst_LIBRARIES = libautocrypt.a -libautocrypt_a_SOURCES = autocrypt.c autocrypt.h +libautocrypt_a_SOURCES = autocrypt.c autocrypt.h autocrypt_db.c autocrypt_private.h \ + autocrypt_schema.c diff --git a/autocrypt/autocrypt.c b/autocrypt/autocrypt.c index 6aecf6fe..fe40b613 100644 --- a/autocrypt/autocrypt.c +++ b/autocrypt/autocrypt.c @@ -22,13 +22,68 @@ #include "mutt.h" #include "autocrypt.h" +#include "autocrypt_private.h" -void mutt_autocrypt_init (void) +#include <errno.h> + +static int autocrypt_dir_init (int can_create) { + int rv = 0; + struct stat sb; + BUFFER *prompt = NULL; + + if (!stat (AutocryptDir, &sb)) + return 0; + + if (!can_create) + return -1; + + prompt = mutt_buffer_pool_get (); + mutt_buffer_printf (prompt, _("%s does not exist. Create it?"), AutocryptDir); + if (mutt_yesorno (mutt_b2s (prompt), MUTT_YES) == MUTT_YES) + { + if (mutt_mkdir (AutocryptDir, 0700) < 0) + { + mutt_error ( _("Can't create %s: %s."), AutocryptDir, strerror (errno)); + mutt_sleep (0); + rv = -1; + } + } + + mutt_buffer_pool_release (&prompt); + return rv; +} + +int mutt_autocrypt_init (int can_create) +{ + if (AutocryptDB) + return 0; + + if (!option (OPTAUTOCRYPT) || !AutocryptDir) + return -1; + + if (autocrypt_dir_init (can_create)) + goto bail; + + if (mutt_autocrypt_db_init (can_create)) + goto bail; + + /* mutt_autocrypt_gpgme_init() + * - init gpgme + * - create key if doesn't exist + * - perhaps should query account table and if empty do that? + */ dprint (1, (debugfile, "In mutt_autocrypt_init()\n")); + return 0; + +bail: + unset_option (OPTAUTOCRYPT); + mutt_autocrypt_db_close (); + return -1; } void mutt_autocrypt_cleanup (void) { + mutt_autocrypt_db_close (); dprint (1, (debugfile, "In mutt_autocrypt_cleanup()\n")); } diff --git a/autocrypt/autocrypt.h b/autocrypt/autocrypt.h index f866e76b..2429539e 100644 --- a/autocrypt/autocrypt.h +++ b/autocrypt/autocrypt.h @@ -19,7 +19,11 @@ #ifndef _AUTOCRYPT_H #define _AUTOCRYPT_H 1 -void mutt_autocrypt_init (void); +#include <sqlite3.h> + +WHERE sqlite3 *AutocryptDB; + +int mutt_autocrypt_init (int); void mutt_autocrypt_cleanup (void); #endif diff --git a/autocrypt/autocrypt_db.c b/autocrypt/autocrypt_db.c new file mode 100644 index 00000000..e7baa603 --- /dev/null +++ b/autocrypt/autocrypt_db.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mutt.h" +#include "autocrypt.h" +#include "autocrypt_private.h" + +static int autocrypt_db_create (const char *db_path) +{ + if (sqlite3_open_v2 (db_path, + &AutocryptDB, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, + NULL) != SQLITE_OK) + { + mutt_error (_("Unable to open autocrypt database %s"), db_path); + mutt_sleep (0); + return -1; + } + return mutt_autocrypt_schema_init (); +} + +int mutt_autocrypt_db_init (int can_create) +{ + int rv = -1; + BUFFER *db_path = NULL; + struct stat sb; + + if (AutocryptDB) + return 0; + + if (!option (OPTAUTOCRYPT) || !AutocryptDir) + return -1; + + db_path = mutt_buffer_pool_get (); + mutt_buffer_concat_path (db_path, AutocryptDir, "autocrypt.db"); + if (stat (mutt_b2s (db_path), &sb)) + { + if (!can_create || autocrypt_db_create (mutt_b2s (db_path))) + goto cleanup; + } + else + { + if (sqlite3_open_v2 (mutt_b2s (db_path), + &AutocryptDB, + SQLITE_OPEN_READWRITE, + NULL) != SQLITE_OK) + { + mutt_error (_("Unable to open autocrypt database %s"), mutt_b2s (db_path)); + mutt_sleep (0); + goto cleanup; + } + } + + if (mutt_autocrypt_schema_update ()) + goto cleanup; + + rv = 0; + +cleanup: + mutt_buffer_pool_release (&db_path); + return rv; +} + +void mutt_autocrypt_db_close (void) +{ + if (!AutocryptDB) + return; + + /* TODO: + * call sqlite3_finalize () for each prepared statement + */ + + sqlite3_close_v2 (AutocryptDB); + AutocryptDB = NULL; +} diff --git a/autocrypt/autocrypt_private.h b/autocrypt/autocrypt_private.h new file mode 100644 index 00000000..56f0dda3 --- /dev/null +++ b/autocrypt/autocrypt_private.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _AUTOCRYPT_PRIVATE_H +#define _AUTOCRYPT_PRIVATE_H 1 + +int mutt_autocrypt_db_init (int can_create); +void mutt_autocrypt_db_close (void); + +int mutt_autocrypt_schema_init (void); +int mutt_autocrypt_schema_update (void); + + +#endif diff --git a/autocrypt/autocrypt_schema.c b/autocrypt/autocrypt_schema.c new file mode 100644 index 00000000..cb9d63d6 --- /dev/null +++ b/autocrypt/autocrypt_schema.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us> + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mutt.h" +#include "autocrypt.h" +#include "autocrypt_private.h" + +int mutt_autocrypt_schema_init (void) +{ + const char *schema; + char *errmsg = NULL; + + schema = + "BEGIN TRANSACTION; " + + "CREATE TABLE account (" + "email_addr text primary key not null, " + "keyid text, " + "keydata text, " + "prefer_encrypt int, " + "enabled int);" + + "CREATE TABLE peer (" + "email_addr text primary key not null, " + "last_seen int, " + "autocrypt_timestamp int, " + "keyid text, " + "keydata text, " + "prefer_encrypt int, " + "gossip_timestamp int, " + "gossip_keyid text, " + "gossip_keydata text);" + + "CREATE TABLE peer_history (" + "peer_email_addr text not null, " + "email_msgid text, " + "timestamp int, " + "keydata text);" + + "CREATE INDEX peer_history_email " + "ON peer_history (" + "peer_email_addr);" + + "CREATE TABLE gossip_history (" + "peer_email_addr text not null, " + "sender_email_addr text, " + "email_msgid text, " + "timestamp int, " + "gossip_keydata text);" + + "CREATE INDEX gossip_history_email " + "ON gossip_history (" + "peer_email_addr);" + + "CREATE TABLE schema (" + "version int);" + + "INSERT into schema (version) values (1);" + + "COMMIT TRANSACTION"; + + if (sqlite3_exec (AutocryptDB, schema, NULL, NULL, &errmsg) != SQLITE_OK) + { + dprint (1, (debugfile, "mutt_autocrypt_schema_init() returned %s\n", errmsg)); + sqlite3_free (errmsg); + return -1; + } + return 0; +} + +int mutt_autocrypt_schema_update (void) +{ + sqlite3_stmt *stmt = NULL; + int rv = -1, version; + + if (sqlite3_prepare_v2 ( + AutocryptDB, + "SELECT version FROM schema;", + -1, + &stmt, + NULL) != SQLITE_OK) + goto cleanup; + + if (sqlite3_step (stmt) != SQLITE_ROW) + goto cleanup; + + version = sqlite3_column_int (stmt, 0); + + if (version > 1) + { + /* L10N: + The autocrypt database keeps track of schema version numbers. + This error occurs if the version number is too high. + Presumably because this is an old version of mutt and the + database was upgraded by a future version. + */ + mutt_error _("Autocrypt database version is too new"); + mutt_sleep (0); + goto cleanup; + } + + /* TODO: schema version upgrades go here. + * Bump one by one, each update inside a transaction. */ + + rv = 0; + +cleanup: + sqlite3_finalize (stmt); + return rv; +} |