NeoMutt  2019-12-07-168-gc45f47
Teaching an old dog new tricks
DOXYGEN
dump.c File Reference

Dump all the config. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "mutt/lib.h"
#include "dump.h"
#include "set.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 626 of file muttlib.c.

627 {
628  if (!buf)
629  return;
630 
631  char *p = buf, *q = buf;
632  size_t len;
633  enum UrlScheme scheme;
634  char tmp[PATH_MAX];
635 
636  scheme = url_check_scheme(buf);
637 
638  if ((scheme == U_IMAP) || (scheme == U_IMAPS))
639  {
640  imap_pretty_mailbox(buf, buflen, C_Folder);
641  return;
642  }
643 
644  if (scheme == U_NOTMUCH)
645  return;
646 
647  /* if buf is an url, only collapse path component */
648  if (scheme != U_UNKNOWN)
649  {
650  p = strchr(buf, ':') + 1;
651  if (strncmp(p, "//", 2) == 0)
652  q = strchr(p + 2, '/');
653  if (!q)
654  q = strchr(p, '\0');
655  p = q;
656  }
657 
658  /* cleanup path */
659  if (strstr(p, "//") || strstr(p, "/./"))
660  {
661  /* first attempt to collapse the pathname, this is more
662  * lightweight than realpath() and doesn't resolve links */
663  while (*p)
664  {
665  if ((p[0] == '/') && (p[1] == '/'))
666  {
667  *q++ = '/';
668  p += 2;
669  }
670  else if ((p[0] == '/') && (p[1] == '.') && (p[2] == '/'))
671  {
672  *q++ = '/';
673  p += 3;
674  }
675  else
676  *q++ = *p++;
677  }
678  *q = '\0';
679  }
680  else if (strstr(p, "..") && ((scheme == U_UNKNOWN) || (scheme == U_FILE)) &&
681  realpath(p, tmp))
682  {
683  mutt_str_strfcpy(p, tmp, buflen - (p - buf));
684  }
685 
686  if ((len = mutt_str_startswith(buf, C_Folder, CASE_MATCH)) && (buf[len] == '/'))
687  {
688  *buf++ = '=';
689  memmove(buf, buf + len, mutt_str_strlen(buf + len) + 1);
690  }
691  else if ((len = mutt_str_startswith(buf, HomeDir, CASE_MATCH)) && (buf[len] == '/'))
692  {
693  *buf++ = '~';
694  memmove(buf, buf + len - 1, mutt_str_strlen(buf + len - 1) + 1);
695  }
696 }
Url is notmuch://.
Definition: url.h:45
Url is imaps://.
Definition: url.h:39
Url wasn&#39;t recognised.
Definition: url.h:34
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:731
Url is imap://.
Definition: url.h:38
Match case when comparing strings.
Definition: string2.h:67
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
enum UrlScheme url_check_scheme(const char *s)
Check the protocol of a URL.
Definition: url.c:132
UrlScheme
All recognised Url types.
Definition: url.h:32
WHERE char * HomeDir
User&#39;s home directory.
Definition: globals.h:49
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:119
#define PATH_MAX
Definition: mutt.h:50
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
Url is file://.
Definition: url.h:35
+ 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 '\n':
57  len += mutt_buffer_addstr(buf, "\\n");
58  break;
59  case '\r':
60  len += mutt_buffer_addstr(buf, "\\r");
61  break;
62  case '\t':
63  len += mutt_buffer_addstr(buf, "\\t");
64  break;
65  default:
66  if ((*src == '\\') || (*src == '"'))
67  len += mutt_buffer_addch(buf, '\\');
68  len += mutt_buffer_addch(buf, src[0]);
69  }
70  }
71  return len;
72 }
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
+ 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 80 of file dump.c.

81 {
82  if (!buf || !str)
83  return 0;
84 
85  int len = 0;
86 
87  len += mutt_buffer_addch(buf, '"');
88  len += escape_string(buf, str);
89  len += mutt_buffer_addch(buf, '"');
90 
91  return len;
92 }
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:46
+ 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 103 of file dump.c.

105 {
106  if (!he || !value || !fp)
107  return;
108 
109  const char *name = he->key.strkey;
110 
111  if ((flags & CS_DUMP_ONLY_CHANGED) &&
112  (!initial || (mutt_str_strcmp(value->data, initial->data) == 0)))
113  return;
114 
115  if (he->type == DT_SYNONYM)
116  {
117  const struct ConfigDef *cdef = he->data;
118  const char *syn = (const char *) cdef->initial;
119  fprintf(fp, "# synonym: %s -> %s\n", name, syn);
120  return;
121  }
122 
123  bool show_name = !(flags & CS_DUMP_HIDE_NAME);
124  bool show_value = !(flags & CS_DUMP_HIDE_VALUE);
125 
126  if (show_name && show_value)
127  fprintf(fp, "set ");
128  if (show_name)
129  fprintf(fp, "%s", name);
130  if (show_name && show_value)
131  fprintf(fp, " = ");
132  if (show_value)
133  fprintf(fp, "%s", value->data);
134  if (show_name || show_value)
135  fprintf(fp, "\n");
136 
137  if (flags & CS_DUMP_SHOW_DEFAULTS)
138  {
139  const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
140  if (cst)
141  fprintf(fp, "# %s %s %s\n", cst->name, name, value->data);
142  }
143 }
union HashKey key
Definition: hash.h:45
Type definition for a config item.
Definition: set.h:149
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
intptr_t initial
Initial value.
Definition: set.h:139
#define CS_DUMP_HIDE_VALUE
Do not print the value of the config item.
Definition: dump.h:40
Config item definition.
Definition: set.h:134
#define CS_DUMP_SHOW_DEFAULTS
Show the default value for the config item.
Definition: dump.h:41
const char * name
Definition: pgpmicalg.c:46
char * data
Pointer to data.
Definition: buffer.h:35
void * data
Definition: hash.h:46
#define DT_SYNONYM
synonym for another variable
Definition: types.h:41
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:226
const char * name
Name of the type, e.g. "String".
Definition: set.h:151
const char * strkey
Definition: hash.h:35
int type
Definition: hash.h:44
#define CS_DUMP_HIDE_NAME
Do not print the name of the config item.
Definition: dump.h:39
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ 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 151 of file dump.c.

152 {
153  if (!cs)
154  return false;
155 
156  struct HashElem *he = NULL;
157 
158  struct HashElem **list = get_elem_list(cs);
159  if (!list)
160  return false; /* LCOV_EXCL_LINE */
161 
162  bool result = true;
163 
164  struct Buffer value = mutt_buffer_make(256);
165  struct Buffer initial = mutt_buffer_make(256);
166  struct Buffer tmp = mutt_buffer_make(256);
167 
168  for (size_t i = 0; list[i]; i++)
169  {
170  mutt_buffer_reset(&value);
171  mutt_buffer_reset(&initial);
172  he = list[i];
173  const int type = DTYPE(he->type);
174 
175  if ((type == DT_SYNONYM) && !(flags & CS_DUMP_SHOW_SYNONYMS))
176  continue;
177 
178  if ((he->type & DT_DEPRECATED) && !(flags & CS_DUMP_SHOW_DEPRECATED))
179  continue;
180 
181  // if ((type == DT_DISABLED) && !(flags & CS_DUMP_SHOW_DISABLED))
182  // continue;
183 
184  if (type != DT_SYNONYM)
185  {
186  /* If necessary, get the current value */
187  if ((flags & CS_DUMP_ONLY_CHANGED) || !(flags & CS_DUMP_HIDE_VALUE) ||
188  (flags & CS_DUMP_SHOW_DEFAULTS))
189  {
190  int rc = cs_he_string_get(cs, he, &value);
191  if (CSR_RESULT(rc) != CSR_SUCCESS)
192  {
193  result = false; /* LCOV_EXCL_LINE */
194  break; /* LCOV_EXCL_LINE */
195  }
196 
197  const struct ConfigDef *cdef = he->data;
198  if ((type == DT_STRING) && IS_SENSITIVE(*cdef) &&
199  (flags & CS_DUMP_HIDE_SENSITIVE) && !mutt_buffer_is_empty(&value))
200  {
201  mutt_buffer_reset(&value);
202  mutt_buffer_addstr(&value, "***");
203  }
204 
205  if (IS_PATH(he) && (value.data[0] == '/'))
206  mutt_pretty_mailbox(value.data, value.dsize);
207 
208  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
209  (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
210  {
211  mutt_buffer_reset(&tmp);
212  pretty_var(value.data, &tmp);
213  mutt_buffer_strcpy(&value, tmp.data);
214  }
215  }
216 
217  /* If necessary, get the default value */
218  if (flags & (CS_DUMP_ONLY_CHANGED | CS_DUMP_SHOW_DEFAULTS))
219  {
220  int rc = cs_he_initial_get(cs, he, &initial);
221  if (CSR_RESULT(rc) != CSR_SUCCESS)
222  {
223  result = false; /* LCOV_EXCL_LINE */
224  break; /* LCOV_EXCL_LINE */
225  }
226 
227  if (IS_PATH(he) && !(he->type & DT_MAILBOX))
228  mutt_pretty_mailbox(initial.data, initial.dsize);
229 
230  if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
231  (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
232  {
233  mutt_buffer_reset(&tmp);
234  pretty_var(initial.data, &tmp);
235  mutt_buffer_strcpy(&initial, tmp.data);
236  }
237  }
238  }
239 
240  dump_config_neo(cs, he, &value, &initial, flags, fp);
241  }
242 
243  FREE(&list);
244  mutt_buffer_dealloc(&value);
245  mutt_buffer_dealloc(&initial);
246  mutt_buffer_dealloc(&tmp);
247 
248  return result;
249 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define DT_LONG
a number (long)
Definition: types.h:33
#define IS_PATH(x)
Definition: types.h:55
#define CSR_RESULT(x)
Definition: set.h:53
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:62
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
#define CS_DUMP_NO_ESCAPING
Do not escape special chars, or quote the string.
Definition: dump.h:38
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
#define IS_SENSITIVE(x)
Definition: types.h:54
#define CS_DUMP_HIDE_VALUE
Do not print the value of the config item.
Definition: dump.h:40
Config item definition.
Definition: set.h:134
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:36
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:43
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:37
#define CS_DUMP_SHOW_DEPRECATED
Show config items that aren&#39;t used any more.
Definition: dump.h:44
#define CS_DUMP_SHOW_DEFAULTS
Show the default value for the config item.
Definition: dump.h:41
size_t dsize
Length of data.
Definition: buffer.h:37
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:103
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:37
#define DT_STRING
a string
Definition: types.h:40
#define DT_DEPRECATED
Config item shouldn&#39;t be used any more.
Definition: types.h:77
#define DT_MAILBOX
Don&#39;t perform path expansions.
Definition: types.h:47
char * data
Pointer to data.
Definition: buffer.h:35
#define CS_DUMP_SHOW_SYNONYMS
Show synonyms and the config items they&#39;re linked to.
Definition: dump.h:43
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:626
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:480
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
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:615
void * data
Definition: hash.h:46
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:80
#define DT_SYNONYM
synonym for another variable
Definition: types.h:41
int type
Definition: hash.h:44
#define FREE(x)
Definition: memory.h:40
The item stored in a Hash Table.
Definition: hash.h:42
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
#define DT_NUMBER
a number
Definition: types.h:35
#define DT_BOOL
boolean option
Definition: types.h:30
+ Here is the call graph for this function:
+ Here is the caller graph for this function: