mutt stable branch with some hacks

Add database and schema initialization.

Add mutt_mkdir() library function supporting recursive mkdir.

+353 -4
+2 -1
autocrypt/Makefile.am
··· 7 7 8 8 noinst_LIBRARIES = libautocrypt.a 9 9 10 - libautocrypt_a_SOURCES = autocrypt.c autocrypt.h 10 + libautocrypt_a_SOURCES = autocrypt.c autocrypt.h autocrypt_db.c autocrypt_private.h \ 11 + autocrypt_schema.c
+56 -1
autocrypt/autocrypt.c
··· 22 22 23 23 #include "mutt.h" 24 24 #include "autocrypt.h" 25 + #include "autocrypt_private.h" 25 26 26 - void mutt_autocrypt_init (void) 27 + #include <errno.h> 28 + 29 + static int autocrypt_dir_init (int can_create) 30 + { 31 + int rv = 0; 32 + struct stat sb; 33 + BUFFER *prompt = NULL; 34 + 35 + if (!stat (AutocryptDir, &sb)) 36 + return 0; 37 + 38 + if (!can_create) 39 + return -1; 40 + 41 + prompt = mutt_buffer_pool_get (); 42 + mutt_buffer_printf (prompt, _("%s does not exist. Create it?"), AutocryptDir); 43 + if (mutt_yesorno (mutt_b2s (prompt), MUTT_YES) == MUTT_YES) 44 + { 45 + if (mutt_mkdir (AutocryptDir, 0700) < 0) 46 + { 47 + mutt_error ( _("Can't create %s: %s."), AutocryptDir, strerror (errno)); 48 + mutt_sleep (0); 49 + rv = -1; 50 + } 51 + } 52 + 53 + mutt_buffer_pool_release (&prompt); 54 + return rv; 55 + } 56 + 57 + int mutt_autocrypt_init (int can_create) 27 58 { 59 + if (AutocryptDB) 60 + return 0; 61 + 62 + if (!option (OPTAUTOCRYPT) || !AutocryptDir) 63 + return -1; 64 + 65 + if (autocrypt_dir_init (can_create)) 66 + goto bail; 67 + 68 + if (mutt_autocrypt_db_init (can_create)) 69 + goto bail; 70 + 71 + /* mutt_autocrypt_gpgme_init() 72 + * - init gpgme 73 + * - create key if doesn't exist 74 + * - perhaps should query account table and if empty do that? 75 + */ 28 76 dprint (1, (debugfile, "In mutt_autocrypt_init()\n")); 77 + return 0; 78 + 79 + bail: 80 + unset_option (OPTAUTOCRYPT); 81 + mutt_autocrypt_db_close (); 82 + return -1; 29 83 } 30 84 31 85 void mutt_autocrypt_cleanup (void) 32 86 { 87 + mutt_autocrypt_db_close (); 33 88 dprint (1, (debugfile, "In mutt_autocrypt_cleanup()\n")); 34 89 }
+5 -1
autocrypt/autocrypt.h
··· 19 19 #ifndef _AUTOCRYPT_H 20 20 #define _AUTOCRYPT_H 1 21 21 22 - void mutt_autocrypt_init (void); 22 + #include <sqlite3.h> 23 + 24 + WHERE sqlite3 *AutocryptDB; 25 + 26 + int mutt_autocrypt_init (int); 23 27 void mutt_autocrypt_cleanup (void); 24 28 25 29 #endif
+94
autocrypt/autocrypt_db.c
··· 1 + /* 2 + * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 + */ 18 + 19 + #if HAVE_CONFIG_H 20 + # include "config.h" 21 + #endif 22 + 23 + #include "mutt.h" 24 + #include "autocrypt.h" 25 + #include "autocrypt_private.h" 26 + 27 + static int autocrypt_db_create (const char *db_path) 28 + { 29 + if (sqlite3_open_v2 (db_path, 30 + &AutocryptDB, 31 + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, 32 + NULL) != SQLITE_OK) 33 + { 34 + mutt_error (_("Unable to open autocrypt database %s"), db_path); 35 + mutt_sleep (0); 36 + return -1; 37 + } 38 + return mutt_autocrypt_schema_init (); 39 + } 40 + 41 + int mutt_autocrypt_db_init (int can_create) 42 + { 43 + int rv = -1; 44 + BUFFER *db_path = NULL; 45 + struct stat sb; 46 + 47 + if (AutocryptDB) 48 + return 0; 49 + 50 + if (!option (OPTAUTOCRYPT) || !AutocryptDir) 51 + return -1; 52 + 53 + db_path = mutt_buffer_pool_get (); 54 + mutt_buffer_concat_path (db_path, AutocryptDir, "autocrypt.db"); 55 + if (stat (mutt_b2s (db_path), &sb)) 56 + { 57 + if (!can_create || autocrypt_db_create (mutt_b2s (db_path))) 58 + goto cleanup; 59 + } 60 + else 61 + { 62 + if (sqlite3_open_v2 (mutt_b2s (db_path), 63 + &AutocryptDB, 64 + SQLITE_OPEN_READWRITE, 65 + NULL) != SQLITE_OK) 66 + { 67 + mutt_error (_("Unable to open autocrypt database %s"), mutt_b2s (db_path)); 68 + mutt_sleep (0); 69 + goto cleanup; 70 + } 71 + } 72 + 73 + if (mutt_autocrypt_schema_update ()) 74 + goto cleanup; 75 + 76 + rv = 0; 77 + 78 + cleanup: 79 + mutt_buffer_pool_release (&db_path); 80 + return rv; 81 + } 82 + 83 + void mutt_autocrypt_db_close (void) 84 + { 85 + if (!AutocryptDB) 86 + return; 87 + 88 + /* TODO: 89 + * call sqlite3_finalize () for each prepared statement 90 + */ 91 + 92 + sqlite3_close_v2 (AutocryptDB); 93 + AutocryptDB = NULL; 94 + }
+29
autocrypt/autocrypt_private.h
··· 1 + /* 2 + * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 + */ 18 + 19 + #ifndef _AUTOCRYPT_PRIVATE_H 20 + #define _AUTOCRYPT_PRIVATE_H 1 21 + 22 + int mutt_autocrypt_db_init (int can_create); 23 + void mutt_autocrypt_db_close (void); 24 + 25 + int mutt_autocrypt_schema_init (void); 26 + int mutt_autocrypt_schema_update (void); 27 + 28 + 29 + #endif
+129
autocrypt/autocrypt_schema.c
··· 1 + /* 2 + * Copyright (C) 2019 Kevin J. McCarthy <kevin@8t8.us> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 + */ 18 + 19 + #if HAVE_CONFIG_H 20 + # include "config.h" 21 + #endif 22 + 23 + #include "mutt.h" 24 + #include "autocrypt.h" 25 + #include "autocrypt_private.h" 26 + 27 + int mutt_autocrypt_schema_init (void) 28 + { 29 + const char *schema; 30 + char *errmsg = NULL; 31 + 32 + schema = 33 + "BEGIN TRANSACTION; " 34 + 35 + "CREATE TABLE account (" 36 + "email_addr text primary key not null, " 37 + "keyid text, " 38 + "keydata text, " 39 + "prefer_encrypt int, " 40 + "enabled int);" 41 + 42 + "CREATE TABLE peer (" 43 + "email_addr text primary key not null, " 44 + "last_seen int, " 45 + "autocrypt_timestamp int, " 46 + "keyid text, " 47 + "keydata text, " 48 + "prefer_encrypt int, " 49 + "gossip_timestamp int, " 50 + "gossip_keyid text, " 51 + "gossip_keydata text);" 52 + 53 + "CREATE TABLE peer_history (" 54 + "peer_email_addr text not null, " 55 + "email_msgid text, " 56 + "timestamp int, " 57 + "keydata text);" 58 + 59 + "CREATE INDEX peer_history_email " 60 + "ON peer_history (" 61 + "peer_email_addr);" 62 + 63 + "CREATE TABLE gossip_history (" 64 + "peer_email_addr text not null, " 65 + "sender_email_addr text, " 66 + "email_msgid text, " 67 + "timestamp int, " 68 + "gossip_keydata text);" 69 + 70 + "CREATE INDEX gossip_history_email " 71 + "ON gossip_history (" 72 + "peer_email_addr);" 73 + 74 + "CREATE TABLE schema (" 75 + "version int);" 76 + 77 + "INSERT into schema (version) values (1);" 78 + 79 + "COMMIT TRANSACTION"; 80 + 81 + if (sqlite3_exec (AutocryptDB, schema, NULL, NULL, &errmsg) != SQLITE_OK) 82 + { 83 + dprint (1, (debugfile, "mutt_autocrypt_schema_init() returned %s\n", errmsg)); 84 + sqlite3_free (errmsg); 85 + return -1; 86 + } 87 + return 0; 88 + } 89 + 90 + int mutt_autocrypt_schema_update (void) 91 + { 92 + sqlite3_stmt *stmt = NULL; 93 + int rv = -1, version; 94 + 95 + if (sqlite3_prepare_v2 ( 96 + AutocryptDB, 97 + "SELECT version FROM schema;", 98 + -1, 99 + &stmt, 100 + NULL) != SQLITE_OK) 101 + goto cleanup; 102 + 103 + if (sqlite3_step (stmt) != SQLITE_ROW) 104 + goto cleanup; 105 + 106 + version = sqlite3_column_int (stmt, 0); 107 + 108 + if (version > 1) 109 + { 110 + /* L10N: 111 + The autocrypt database keeps track of schema version numbers. 112 + This error occurs if the version number is too high. 113 + Presumably because this is an old version of mutt and the 114 + database was upgraded by a future version. 115 + */ 116 + mutt_error _("Autocrypt database version is too new"); 117 + mutt_sleep (0); 118 + goto cleanup; 119 + } 120 + 121 + /* TODO: schema version upgrades go here. 122 + * Bump one by one, each update inside a transaction. */ 123 + 124 + rv = 0; 125 + 126 + cleanup: 127 + sqlite3_finalize (stmt); 128 + return rv; 129 + }
+35
lib.c
··· 307 307 return (s); 308 308 } 309 309 310 + int mutt_mkdir (char *path, mode_t mode) 311 + { 312 + struct stat sb; 313 + char *s; 314 + int rv = -1; 315 + 316 + if (stat (path, &sb) >= 0) 317 + return 0; 318 + 319 + s = path; 320 + do 321 + { 322 + s = strchr (s + 1, '/'); 323 + if (s) 324 + *s = '\0'; 325 + if (stat (path, &sb) < 0) 326 + { 327 + if (errno != ENOENT) 328 + goto cleanup; 329 + if (mkdir (path, mode) < 0) 330 + goto cleanup; 331 + } 332 + if (s) 333 + *s = '/'; 334 + } while (s); 335 + 336 + rv = 0; 337 + 338 + cleanup: 339 + if (s) 340 + *s = '/'; 341 + 342 + return rv; 343 + } 344 + 310 345 void mutt_unlink (const char *s) 311 346 { 312 347 int fd;
+1
lib.h
··· 218 218 void mutt_remove_trailing_ws (char *); 219 219 void mutt_sanitize_filename (char *, short); 220 220 void mutt_str_replace (char **p, const char *s); 221 + int mutt_mkdir (char *path, mode_t mode); 221 222 void mutt_str_adjust (char **p); 222 223 void mutt_unlink (const char *); 223 224 void safe_free (void *);
+2 -1
main.c
··· 868 868 /* Initialize crypto backends. */ 869 869 crypt_init (); 870 870 #ifdef USE_AUTOCRYPT 871 - mutt_autocrypt_init (); 871 + if (option (OPTAUTOCRYPT)) 872 + mutt_autocrypt_init (!(sendflags & SENDBATCH)); 872 873 #endif 873 874 874 875 if (newMagic)