NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
dlgautocrypt.c
Go to the documentation of this file.
1 
69 #include "config.h"
70 #include <stdbool.h>
71 #include <stdint.h>
72 #include <stdio.h>
73 #include "private.h"
74 #include "mutt/lib.h"
75 #include "address/lib.h"
76 #include "config/lib.h"
77 #include "core/lib.h"
78 #include "gui/lib.h"
79 #include "lib.h"
80 #include "menu/lib.h"
81 #include "question/lib.h"
82 #include "format_flags.h"
83 #include "muttlib.h"
84 #include "opcodes.h"
85 
90 {
91  int num;
93  struct Address *addr;
94 };
95 
97 static const struct Mapping AutocryptAcctHelp[] = {
98  // clang-format off
99  { N_("Exit"), OP_EXIT },
100  /* L10N: Autocrypt Account Menu Help line:
101  create new account */
102  { N_("Create"), OP_AUTOCRYPT_CREATE_ACCT },
103  /* L10N: Autocrypt Account Menu Help line:
104  delete account */
105  { N_("Delete"), OP_AUTOCRYPT_DELETE_ACCT },
106  /* L10N: Autocrypt Account Menu Help line:
107  toggle an account active/inactive
108  The words here are abbreviated to keep the help line compact.
109  It currently has the content:
110  q:Exit c:Create D:Delete a:Tgl Active p:Prf Encr ?:Help */
111  { N_("Tgl Active"), OP_AUTOCRYPT_TOGGLE_ACTIVE },
112  /* L10N: Autocrypt Account Menu Help line:
113  toggle "prefer-encrypt" on an account
114  The words here are abbreviated to keep the help line compact.
115  It currently has the content:
116  q:Exit c:Create D:Delete a:Tgl Active p:Prf Encr ?:Help */
117  { N_("Prf Encr"), OP_AUTOCRYPT_TOGGLE_PREFER },
118  { N_("Help"), OP_HELP },
119  { NULL, 0 }
120  // clang-format on
121 };
122 
134 static const char *autocrypt_format_str(char *buf, size_t buflen, size_t col, int cols,
135  char op, const char *src, const char *prec,
136  const char *if_str, const char *else_str,
137  intptr_t data, MuttFormatFlags flags)
138 {
139  struct AccountEntry *entry = (struct AccountEntry *) data;
140  char tmp[128];
141 
142  switch (op)
143  {
144  case 'a':
145  mutt_format_s(buf, buflen, prec, entry->addr->mailbox);
146  break;
147  case 'k':
148  mutt_format_s(buf, buflen, prec, entry->account->keyid);
149  break;
150  case 'n':
151  snprintf(tmp, sizeof(tmp), "%%%sd", prec);
152  snprintf(buf, buflen, tmp, entry->num);
153  break;
154  case 'p':
155  if (entry->account->prefer_encrypt)
156  {
157  /* L10N: Autocrypt Account menu.
158  flag that an account has prefer-encrypt set */
159  mutt_format_s(buf, buflen, prec, _("prefer encrypt"));
160  }
161  else
162  {
163  /* L10N: Autocrypt Account menu.
164  flag that an account has prefer-encrypt unset;
165  thus encryption will need to be manually enabled. */
166  mutt_format_s(buf, buflen, prec, _("manual encrypt"));
167  }
168  break;
169  case 's':
170  if (entry->account->enabled)
171  {
172  /* L10N: Autocrypt Account menu.
173  flag that an account is enabled/active */
174  mutt_format_s(buf, buflen, prec, _("active"));
175  }
176  else
177  {
178  /* L10N: Autocrypt Account menu.
179  flag that an account is disabled/inactive */
180  mutt_format_s(buf, buflen, prec, _("inactive"));
181  }
182  break;
183  }
184 
185  return (src);
186 }
187 
191 static void autocrypt_make_entry(struct Menu *menu, char *buf, size_t buflen, int num)
192 {
193  struct AccountEntry *entry = &((struct AccountEntry *) menu->mdata)[num];
194 
195  const char *const c_autocrypt_acct_format =
196  cs_subset_string(NeoMutt->sub, "autocrypt_acct_format");
197  mutt_expando_format(buf, buflen, 0, menu->win->state.cols,
198  NONULL(c_autocrypt_acct_format), autocrypt_format_str,
199  (intptr_t) entry, MUTT_FORMAT_ARROWCURSOR);
200 }
201 
205 static void autocrypt_menu_free(struct Menu *menu, void **ptr)
206 {
207  struct AccountEntry *entries = *ptr;
208 
209  for (size_t i = 0; i < menu->max; i++)
210  {
212  mutt_addr_free(&entries[i].addr);
213  }
214 
215  FREE(ptr);
216 }
217 
223 static bool populate_menu(struct Menu *menu)
224 {
225  // Clear out any existing data
226  autocrypt_menu_free(menu, &menu->mdata);
227  menu->max = 0;
228 
229  struct AutocryptAccount **accounts = NULL;
230  int num_accounts = 0;
231 
232  if (mutt_autocrypt_db_account_get_all(&accounts, &num_accounts) < 0)
233  return false;
234 
235  struct AccountEntry *entries =
236  mutt_mem_calloc(num_accounts, sizeof(struct AccountEntry));
237  menu->mdata = entries;
239  menu->max = num_accounts;
240 
241  for (int i = 0; i < num_accounts; i++)
242  {
243  entries[i].num = i + 1;
244  /* note: we are transferring the account pointer to the entries
245  * array, and freeing the accounts array below. the account
246  * will be freed in autocrypt_menu_free(). */
247  entries[i].account = accounts[i];
248 
249  entries[i].addr = mutt_addr_new();
250  entries[i].addr->mailbox = mutt_str_dup(accounts[i]->email_addr);
251  mutt_addr_to_local(entries[i].addr);
252  }
253  FREE(&accounts);
254 
256  return true;
257 }
258 
263 static void toggle_active(struct AccountEntry *entry)
264 {
265  entry->account->enabled = !entry->account->enabled;
266  if (mutt_autocrypt_db_account_update(entry->account) != 0)
267  {
268  entry->account->enabled = !entry->account->enabled;
269  /* L10N: This error message is displayed if a database update of an
270  account record fails for some odd reason. */
271  mutt_error(_("Error updating account record"));
272  }
273 }
274 
279 static void toggle_prefer_encrypt(struct AccountEntry *entry)
280 {
281  entry->account->prefer_encrypt = !entry->account->prefer_encrypt;
283  {
284  entry->account->prefer_encrypt = !entry->account->prefer_encrypt;
285  mutt_error(_("Error updating account record"));
286  }
287 }
288 
295 {
296  if ((nc->event_type != NT_CONFIG) || !nc->global_data || !nc->event_data)
297  return -1;
298 
299  struct EventConfig *ev_c = nc->event_data;
300 
301  if (!mutt_str_equal(ev_c->name, "autocrypt_acct_format"))
302  return 0;
303 
304  struct Menu *menu = nc->global_data;
306  mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
307 
308  return 0;
309 }
310 
319 {
320  if ((nc->event_type != NT_WINDOW) || !nc->global_data || !nc->event_data)
321  return -1;
322 
323  if (nc->event_subtype != NT_WINDOW_DELETE)
324  return 0;
325 
326  struct MuttWindow *win_menu = nc->global_data;
327  struct EventWindow *ev_w = nc->event_data;
328  if (ev_w->win != win_menu)
329  return 0;
330 
331  struct Menu *menu = win_menu->wdata;
332 
335 
336  mutt_debug(LL_DEBUG5, "window delete done\n");
337  return 0;
338 }
339 
345 {
346  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
347  if (!c_autocrypt)
348  return;
349 
350  if (mutt_autocrypt_init(m, false))
351  return;
352 
353  struct MuttWindow *dlg =
355 
356  struct Menu *menu = dlg->wdata;
358 
359  populate_menu(menu);
360 
361  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
362  // L10N: Autocrypt Account Management Menu title
363  sbar_set_title(sbar, _("Autocrypt Accounts"));
364 
365  struct MuttWindow *win_menu = menu->win;
366 
367  // NT_COLOR is handled by the SimpleDialog
370 
371  bool done = false;
372  while (!done)
373  {
374  switch (menu_loop(menu))
375  {
376  case OP_EXIT:
377  done = true;
378  break;
379 
380  case OP_AUTOCRYPT_CREATE_ACCT:
381  if (mutt_autocrypt_account_init(false) == 0)
382  populate_menu(menu);
383  break;
384 
385  case OP_AUTOCRYPT_DELETE_ACCT:
386  {
387  if (!menu->mdata)
388  break;
389 
390  const int index = menu_get_index(menu);
391  struct AccountEntry *entry = ((struct AccountEntry *) menu->mdata) + index;
392  char msg[128];
393  snprintf(msg, sizeof(msg),
394  // L10N: Confirmation message when deleting an autocrypt account
395  _("Really delete account \"%s\"?"), entry->addr->mailbox);
396  if (mutt_yesorno(msg, MUTT_NO) != MUTT_YES)
397  break;
398 
399  if (mutt_autocrypt_db_account_delete(entry->account) == 0)
400  populate_menu(menu);
401 
402  break;
403  }
404 
405  case OP_AUTOCRYPT_TOGGLE_ACTIVE:
406  {
407  if (!menu->mdata)
408  break;
409 
410  const int index = menu_get_index(menu);
411  struct AccountEntry *entry = ((struct AccountEntry *) menu->mdata) + index;
412  toggle_active(entry);
414  break;
415  }
416 
417  case OP_AUTOCRYPT_TOGGLE_PREFER:
418  {
419  if (!menu->mdata)
420  break;
421 
422  const int index = menu_get_index(menu);
423  struct AccountEntry *entry = (struct AccountEntry *) (menu->mdata) + index;
424  toggle_prefer_encrypt(entry);
426  break;
427  }
428  }
429  }
430 
431  simple_dialog_free(&dlg);
432 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
Convenience wrapper for the gui headers.
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string -.
Definition: muttlib.c:780
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
static const char * autocrypt_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the Autocrypt account list - Implements format_t -Expando Description %a Email a...
Definition: dlgautocrypt.c:134
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
Definition: lib.h:67
Data passed to a notification function.
Definition: observer.h:39
struct MuttWindow * win
Window that changed.
Definition: mutt_window.h:217
An Event that happened to a Window.
Definition: mutt_window.h:215
#define mutt_error(...)
Definition: logging.h:88
void mutt_autocrypt_db_account_free(struct AutocryptAccount **ptr)
Free an AutocryptAccount.
Definition: db.c:246
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
A config-change event.
Definition: subset.h:69
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
Window is about to be deleted.
Definition: mutt_window.h:206
An email address.
Definition: address.h:35
char * mailbox
Mailbox and host address.
Definition: address.h:38
Flags to control mutt_expando_format()
All user-callable functions.
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool mutt_addr_to_local(struct Address *a)
Convert an Address from Punycode.
Definition: address.c:1351
char * keyid
Definition: lib.h:106
static void toggle_prefer_encrypt(struct AccountEntry *entry)
Toggle whether an Autocrypt account prefers encryption.
Definition: dlgautocrypt.c:279
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
int mutt_autocrypt_account_init(bool prompt)
Create a new Autocrypt account.
Definition: autocrypt.c:155
Convenience wrapper for the config headers.
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:105
Email Address Handling.
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:43
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
Some miscellaneous functions.
int mutt_autocrypt_db_account_delete(struct AutocryptAccount *acct)
Delete an Account from the Autocrypt database.
Definition: db.c:421
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
bool enabled
Definition: lib.h:109
An entry in the Autocrypt account Menu.
Definition: dlgautocrypt.c:89
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
Convenience wrapper for the core headers.
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
bool prefer_encrypt
false = nopref, true = mutual
Definition: lib.h:108
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
Autocrypt Dialog, dlg_select_autocrypt_account()
Definition: mutt_window.h:79
int mutt_autocrypt_init(struct Mailbox *m, bool can_create)
Initialise Autocrypt.
Definition: autocrypt.c:98
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
static void toggle_active(struct AccountEntry *entry)
Toggle whether an Autocrypt account is active.
Definition: dlgautocrypt.c:263
void * mdata
Private data.
Definition: lib.h:155
A mailbox.
Definition: mailbox.h:81
int mutt_autocrypt_db_account_update(struct AutocryptAccount *acct)
Update Account info in the Autocrypt database.
Definition: db.c:375
struct Address * addr
Definition: dlgautocrypt.c:93
Shared constants/structs that are private to Autocrypt.
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
Ask the user a question.
static int autocrypt_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: dlgautocrypt.c:294
static void autocrypt_make_entry(struct Menu *menu, char *buf, size_t buflen, int num)
Create a line for the Autocrypt account menu - Implements Menu::make_entry() -.
Definition: dlgautocrypt.c:191
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
static int autocrypt_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: dlgautocrypt.c:318
static bool populate_menu(struct Menu *menu)
Add the Autocrypt data to a Menu.
Definition: dlgautocrypt.c:223
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
Autocrypt Account menu.
Definition: type.h:40
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
void * event_data
Data from notify_send()
Definition: observer.h:44
int max
Number of entries in the menu.
Definition: lib.h:71
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
Autocrypt account.
Definition: lib.h:103
void(* mdata_free)(struct Menu *menu, void **ptr)
Definition: lib.h:170
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:867
struct AutocryptAccount * account
Definition: dlgautocrypt.c:92
#define FREE(x)
Definition: memory.h:40
Mapping between user-readable string and a constant.
Definition: mapping.h:31
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:228
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Log at debug level 5.
Definition: logging.h:44
Convenience wrapper for the library headers.
void * wdata
Private data.
Definition: mutt_window.h:145
#define N_(a)
Definition: message.h:32
static void autocrypt_menu_free(struct Menu *menu, void **ptr)
Free the Autocrypt account Menu - Implements Menu::mdata_free() -.
Definition: dlgautocrypt.c:205
const char * name
Name of config item that changed.
Definition: subset.h:72
int mutt_autocrypt_db_account_get_all(struct AutocryptAccount ***accounts, int *num_accounts)
Get all accounts from an Autocrypt database.
Definition: db.c:456
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
void dlg_select_autocrypt_account(struct Mailbox *m)
Display the Autocrypt account Menu.
Definition: dlgautocrypt.c:344