NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
dump.c File Reference
#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "dump.h"
#include "set.h"
#include "subset.h"
#include "types.h"
+ Include dependency graph for dump.c:

Go to the source code of this file.

Functions

void mutt_pretty_mailbox (char *buf, size_t buflen)
 Shorten a mailbox path using '~' or '='. More...
 
size_t escape_string (struct Buffer *buf, const char *src)
 Write a string to a buffer, escaping special characters. More...
 
size_t pretty_var (const char *str, struct Buffer *buf)
 Escape and stringify a config item value. More...
 
void dump_config_neo (struct ConfigSet *cs, struct HashElem *he, struct Buffer *value, struct Buffer *initial, ConfigDumpFlags flags, FILE *fp)
 Dump the config in the style of NeoMutt. More...
 
bool dump_config (struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
 Write all the config to a file. More...
 

Detailed Description

Dump all the config

Authors
  • Richard Russon

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, see http://www.gnu.org/licenses/.

Definition in file dump.c.

Function Documentation

◆ mutt_pretty_mailbox()

void mutt_pretty_mailbox ( char *  buf,
size_t  buflen 
)

Shorten a mailbox path using '~' or '='.

Parameters
bufBuffer containing string to shorten
buflenLength of buffer

Collapse the pathname using ~ or = when possible

Definition at line 523 of file muttlib.c.

524 {
525  if (!buf)
526  return;
527 
528  char *p = buf, *q = buf;
529  size_t len;
530  enum UrlScheme scheme;
531  char tmp[PATH_MAX];
532 
533  scheme = url_check_scheme(buf);
534 
535  if ((scheme == U_IMAP) || (scheme == U_IMAPS))
536  {
537  imap_pretty_mailbox(buf, buflen, C_Folder);
538  return;
539  }
540 
541  if (scheme == U_NOTMUCH)
542  return;
543 
544  /* if buf is an url, only collapse path component */
545  if (scheme != U_UNKNOWN)
546  {
547  p = strchr(buf, ':') + 1;
548  if (mutt_strn_equal(p, "//", 2))
549  q = strchr(p + 2, '/');
550  if (!q)
551  q = strchr(p, '\0');
552  p = q;
553  }
554 
555  /* cleanup path */
556  if (strstr(p, "//") || strstr(p, "/./"))
557  {
558  /* first attempt to collapse the pathname, this is more
559  * lightweight than realpath() and doesn't resolve links */
560  while (*p)
561  {
562  if ((p[0] == '/') && (p[1] == '/'))
563  {
564  *q++ = '/';
565  p += 2;
566  }
567  else if ((p[0] == '/') && (p[1] == '.') && (p[2] == '/'))
568  {
569  *q++ = '/';
570  p += 3;
571  }
572  else
573  *q++ = *p++;
574  }
575  *q = '\0';
576  }
577  else if (strstr(p, "..") && ((scheme == U_UNKNOWN) || (scheme == U_FILE)) &&
578  realpath(p, tmp))
579  {
580  mutt_str_copy(p, tmp, buflen - (p - buf));
581  }
582 
583  if ((len = mutt_str_startswith(buf, C_Folder)) && (buf[len] == '/'))
584  {
585  *buf++ = '=';
586  memmove(buf, buf + len, mutt_str_len(buf + len) + 1);
587  }
588  else if ((len = mutt_str_startswith(buf, HomeDir)) && (buf[len] == '/'))
589  {
590  *buf++ = '~';
591  memmove(buf, buf + len - 1, mutt_str_len(buf + len - 1) + 1);
592  }
593 }
+ Here is the caller graph for this function:

◆ escape_string()

size_t escape_string ( struct Buffer buf,
const char *  src 
)

Write a string to a buffer, escaping special characters.

Parameters
bufBuffer to write to
srcString to write
Return values
numBytes written to buffer

Definition at line 46 of file dump.c.

47 {
48  if (!buf || !src)
49  return 0;
50 
51  size_t len = 0;
52  for (; *src; src++)
53  {
54  switch (*src)
55  {
56  case '\007':
57  len += mutt_buffer_addstr(buf, "\\g");
58  break;
59  case '\n':
60  len += mutt_buffer_addstr(buf, "\\n");
61  break;
62  case '\r':
63  len += mutt_buffer_addstr(buf, "\\r");
64  break;
65  case '\t':
66  len += mutt_buffer_addstr(buf, "\\t");
67  break;
68  default:
69  if ((*src == '\\') || (*src == '"'))
70  len += mutt_buffer_addch(buf, '\\');
71  len += mutt_buffer_addch(buf, src[0]);
72  }
73  }
74  return len;
75 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pretty_var()

size_t pretty_var ( const char *  str,
struct Buffer buf 
)

Escape and stringify a config item value.

Parameters
strString to escape
bufBuffer to write to
Return values
numNumber of bytes written to buffer

Definition at line 83 of file dump.c.

84 {
85  if (!buf || !str)
86  return 0;
87 
88  int len = 0;
89 
90  len += mutt_buffer_addch(buf, '"');
91  len += escape_string(buf, str);
92  len += mutt_buffer_addch(buf, '"');
93 
94  return len;
95 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_config_neo()

void dump_config_neo ( struct ConfigSet cs,
struct HashElem he,
struct Buffer value,
struct Buffer initial,
ConfigDumpFlags  flags,
FILE *  fp 
)

Dump the config in the style of NeoMutt.

Parameters
csConfig items
heHashElem representing config item
valueCurrent value of the config item
initialInitial value of the config item
flagsFlags, see ConfigDumpFlags
fpFile pointer to write to

Definition at line 106 of file dump.c.

108 {
109  if (!he || !value || !fp)
110  return;
111 
112  const char *name = he->key.strkey;
113 
114  if ((flags & CS_DUMP_ONLY_CHANGED) &&
115  (!initial || mutt_str_equal(value->data, initial->data)))
116  {
117  return;
118  }
119 
120  if (he->type == DT_SYNONYM)
121  {
122  const struct ConfigDef *cdef = he->data;
123  const char *syn = (const char *) cdef->initial;
124  fprintf(fp, "# synonym: %s -> %s\n", name, syn);
125  return;
126  }
127 
128  if (flags & CS_DUMP_SHOW_DOCS)
129  {
130  const struct ConfigDef *cdef = he->data;
131  fprintf(fp, "# %s\n", cdef->docs);
132  }
133 
134  bool show_name = !(flags & CS_DUMP_HIDE_NAME);
135  bool show_value = !(flags & CS_DUMP_HIDE_VALUE);
136 
137  if (show_name && show_value)
138  fprintf(fp, "set ");
139  if (show_name)
140  fprintf(fp, "%s", name);
141  if (show_name && show_value)
142  fprintf(fp, " = ");
143  if (show_value)
144  fprintf(fp, "%s", value->data);
145  if (show_name || show_value)
146  fprintf(fp, "\n");
147 
148  if (flags & CS_DUMP_SHOW_DEFAULTS)
149  {
150  const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
151  if (cst)
152  fprintf(fp, "# %s %s %s\n", cst->name, name, value->data);
153  }
154 
155  if (flags & CS_DUMP_SHOW_DOCS)
156  fprintf(fp, "\n");
157 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_config()

bool dump_config ( struct ConfigSet cs,
ConfigDumpFlags  flags,
FILE *  fp 
)

Write all the config to a file.

Parameters
csConfigSet to dump
flagsFlags, see ConfigDumpFlags
fpFile to write config to

Definition at line 165 of file dump.c.

166 {
167  if (!cs)
168  return false;
169 
170  struct HashElem *he = NULL;
171 
172  struct HashElem **list = get_elem_list(cs);
173  if (!list)
174  return false; /* LCOV_EXCL_LINE */
175 
176  bool result = true;
177 
178  struct Buffer value = mutt_buffer_make(256);
179  struct Buffer initial = mutt_buffer_make(256);
180  struct Buffer tmp = mutt_buffer_make(256);
181 
182  for (size_t i = 0; list[i]; i++)
183  {
184  mutt_buffer_reset(&value);
185  mutt_buffer_reset(&initial);
186  he = list[i];
187  const int type = DTYPE(he->type);
188 
189  if ((type == DT_SYNONYM) && !(flags & CS_DUMP_SHOW_SYNONYMS))
190  continue;
191 
192  if ((he->type & DT_DEPRECATED) && !(flags & CS_DUMP_SHOW_DEPRECATED))
193  continue;
194 
195  // if ((type == DT_DISABLED) && !(flags & CS_DUMP_SHOW_DISABLED))
196  // continue;
197 
198  if (type != DT_SYNONYM)
199  {
200  /* If necessary, get the current value */
201  if ((flags & CS_DUMP_ONLY_CHANGED) || !(flags & CS_DUMP_HIDE_VALUE) ||
202  (flags & CS_DUMP_SHOW_DEFAULTS))
203  {
204  int rc = cs_he_string_get(cs, he, &value);
205  if (CSR_RESULT(rc) != CSR_SUCCESS)
206  {
207  result = false; /* LCOV_EXCL_LINE */
208  break; /* LCOV_EXCL_LINE */
209  }
210 
211  const struct ConfigDef *cdef = he->data;
212  if ((type == DT_STRING) && IS_SENSITIVE(*cdef) &&
213  (flags & CS_DUMP_HIDE_SENSITIVE) && !mutt_buffer_is_empty(&value))
214  {
215  mutt_buffer_reset(&value);
216  mutt_buffer_addstr(&value, "***");
217  }
218 
219  if (((type == DT_PATH) || IS_MAILBOX(he)) && (value.data[0] == '/'))
220  mutt_pretty_mailbox(value.data, value.dsize);
221 
222  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
223  (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
224  {
225  mutt_buffer_reset(&tmp);
226  pretty_var(value.data, &tmp);
227  mutt_buffer_strcpy(&value, tmp.data);
228  }
229  }
230 
231  /* If necessary, get the default value */
233  {
234  int rc = cs_he_initial_get(cs, he, &initial);
235  if (CSR_RESULT(rc) != CSR_SUCCESS)
236  {
237  result = false; /* LCOV_EXCL_LINE */
238  break; /* LCOV_EXCL_LINE */
239  }
240 
241  if (((type == DT_PATH) || IS_MAILBOX(he)) && !(he->type & DT_MAILBOX))
242  mutt_pretty_mailbox(initial.data, initial.dsize);
243 
244  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
245  (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
246  {
247  mutt_buffer_reset(&tmp);
248  pretty_var(initial.data, &tmp);
250  }
251  }
252  }
253 
254  dump_config_neo(cs, he, &value, &initial, flags, fp);
255  }
256 
257  FREE(&list);
258  mutt_buffer_dealloc(&value);
260  mutt_buffer_dealloc(&tmp);
261 
262  return result;
263 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:
DT_QUAD
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
DT_MAILBOX
#define DT_MAILBOX
Don't perform path expansions.
Definition: types.h:48
DT_STRING
#define DT_STRING
a string
Definition: types.h:41
CS_DUMP_SHOW_DEPRECATED
#define CS_DUMP_SHOW_DEPRECATED
Show config items that aren't used any more.
Definition: dump.h:44
U_IMAP
@ U_IMAP
Url is imap://.
Definition: url.h:38
CS_DUMP_SHOW_SYNONYMS
#define CS_DUMP_SHOW_SYNONYMS
Show synonyms and the config items they're linked to.
Definition: dump.h:43
imap_pretty_mailbox
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:590
DT_DEPRECATED
#define DT_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:79
HashElem::key
union HashKey key
Key representing the data.
Definition: hash.h:46
mutt_strn_equal
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
CS_DUMP_HIDE_VALUE
#define CS_DUMP_HIDE_VALUE
Do not print the value of the config item.
Definition: dump.h:40
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
url_check_scheme
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition: url.c:221
CSR_SUCCESS
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
cs_he_string_get
int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: set.c:636
CSR_RESULT
#define CSR_RESULT(x)
Definition: set.h:52
UrlScheme
UrlScheme
All recognised Url types.
Definition: url.h:32
HashElem::data
void * data
User-supplied data.
Definition: hash.h:47
U_UNKNOWN
@ U_UNKNOWN
Url wasn't recognised.
Definition: url.h:34
DTYPE
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
ConfigDef::docs
const char * docs
One-liner description.
Definition: set.h:80
FREE
#define FREE(x)
Definition: memory.h:40
U_FILE
@ U_FILE
Url is file://.
Definition: url.h:35
dump_config_neo
void dump_config_neo(struct ConfigSet *cs, struct HashElem *he, struct Buffer *value, struct Buffer *initial, ConfigDumpFlags flags, FILE *fp)
Dump the config in the style of NeoMutt.
Definition: dump.c:106
Buffer::dsize
size_t dsize
Length of data.
Definition: buffer.h:37
CS_DUMP_ONLY_CHANGED
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
PATH_MAX
#define PATH_MAX
Definition: mutt.h:44
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
get_elem_list
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:64
CS_DUMP_NO_ESCAPING
#define CS_DUMP_NO_ESCAPING
Do not escape special chars, or quote the string.
Definition: dump.h:38
escape_string
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:46
mutt_buffer_addch
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
HashKey::strkey
const char * strkey
String key.
Definition: hash.h:36
ConfigDef::name
const char * name
User-visible name.
Definition: set.h:63
DT_SYNONYM
#define DT_SYNONYM
synonym for another variable
Definition: types.h:42
DT_NUMBER
#define DT_NUMBER
a number
Definition: types.h:35
C_Folder
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:96
ConfigDef::initial
intptr_t initial
Initial value.
Definition: set.h:66
DT_LONG
#define DT_LONG
a number (long)
Definition: types.h:33
U_IMAPS
@ U_IMAPS
Url is imaps://.
Definition: url.h:39
pretty_var
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
ConfigSetType::name
const char * name
Name of the type, e.g. "String".
Definition: set.h:91
IS_MAILBOX
#define IS_MAILBOX(x)
Definition: types.h:57
DT_PATH
#define DT_PATH
a path to a file/directory
Definition: types.h:36
CS_DUMP_HIDE_SENSITIVE
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:37
HashElem::type
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
DT_BOOL
#define DT_BOOL
boolean option
Definition: types.h:30
cs_get_type_def
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:237
HashElem
The item stored in a Hash Table.
Definition: hash.h:43
HomeDir
char * HomeDir
User's home directory.
Definition: mutt_globals.h:49
CS_DUMP_HIDE_NAME
#define CS_DUMP_HIDE_NAME
Do not print the name of the config item.
Definition: dump.h:39
ConfigSetType
Type definition for a config item.
Definition: set.h:88
ConfigDef
Config item definition.
Definition: set.h:61
U_NOTMUCH
@ U_NOTMUCH
Url is notmuch://.
Definition: url.h:45
cs_he_initial_get
int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get the initial, or parent, value of a config item.
Definition: set.c:499
CS_DUMP_SHOW_DOCS
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:45
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
CS_DUMP_SHOW_DEFAULTS
#define CS_DUMP_SHOW_DEFAULTS
Show the default value for the config item.
Definition: dump.h:41
mutt_pretty_mailbox
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:523
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
mutt_str_startswith
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
ConfigDef::type
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:64
mutt_buffer_make
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
IS_SENSITIVE
#define IS_SENSITIVE(x)
Definition: types.h:56
mutt_str_copy
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716