NeoMutt  2023-11-03-85-g512e01
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dump.c File Reference

Dump all the config. More...

#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 '='.
 
size_t escape_string (struct Buffer *buf, const char *src)
 Write a string to a buffer, escaping special characters.
 
size_t pretty_var (const char *str, struct Buffer *buf)
 Escape and stringify a config item value.
 
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.
 
bool dump_config (struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
 Write all the config to a file.
 

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 477 of file muttlib.c.

478{
479 if (!buf)
480 return;
481
482 char *p = buf, *q = buf;
483 size_t len;
484 enum UrlScheme scheme;
485 char tmp[PATH_MAX] = { 0 };
486
487 scheme = url_check_scheme(buf);
488
489 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
490 if ((scheme == U_IMAP) || (scheme == U_IMAPS))
491 {
492 imap_pretty_mailbox(buf, buflen, c_folder);
493 return;
494 }
495
496 if (scheme == U_NOTMUCH)
497 return;
498
499 /* if buf is an url, only collapse path component */
500 if (scheme != U_UNKNOWN)
501 {
502 p = strchr(buf, ':') + 1;
503 if (mutt_strn_equal(p, "//", 2))
504 q = strchr(p + 2, '/');
505 if (!q)
506 q = strchr(p, '\0');
507 p = q;
508 }
509
510 /* cleanup path */
511 if (strstr(p, "//") || strstr(p, "/./"))
512 {
513 /* first attempt to collapse the pathname, this is more
514 * lightweight than realpath() and doesn't resolve links */
515 while (*p)
516 {
517 if ((p[0] == '/') && (p[1] == '/'))
518 {
519 *q++ = '/';
520 p += 2;
521 }
522 else if ((p[0] == '/') && (p[1] == '.') && (p[2] == '/'))
523 {
524 *q++ = '/';
525 p += 3;
526 }
527 else
528 {
529 *q++ = *p++;
530 }
531 }
532 *q = '\0';
533 }
534 else if (strstr(p, "..") && ((scheme == U_UNKNOWN) || (scheme == U_FILE)) &&
535 realpath(p, tmp))
536 {
537 mutt_str_copy(p, tmp, buflen - (p - buf));
538 }
539
540 if ((len = mutt_str_startswith(buf, c_folder)) && (buf[len] == '/'))
541 {
542 *buf++ = '=';
543 memmove(buf, buf + len, mutt_str_len(buf + len) + 1);
544 }
545 else if ((len = mutt_str_startswith(buf, HomeDir)) && (buf[len] == '/'))
546 {
547 *buf++ = '~';
548 memmove(buf, buf + len - 1, mutt_str_len(buf + len - 1) + 1);
549 }
550}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
char * HomeDir
User's home directory.
Definition: globals.c:39
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:579
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:497
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:228
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:568
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:653
#define PATH_MAX
Definition: mutt.h:41
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition: url.c:225
UrlScheme
All recognised Url types.
Definition: url.h:34
@ U_NOTMUCH
Url is notmuch://.
Definition: url.h:46
@ U_UNKNOWN
Url wasn't recognised.
Definition: url.h:35
@ U_FILE
Url is file://.
Definition: url.h:36
@ U_IMAP
Url is imap://.
Definition: url.h:39
@ U_IMAPS
Url is imaps://.
Definition: url.h:40
+ Here is the call graph for this function:
+ 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 += buf_addstr(buf, "\\g");
58 break;
59 case '\n':
60 len += buf_addstr(buf, "\\n");
61 break;
62 case '\r':
63 len += buf_addstr(buf, "\\r");
64 break;
65 case '\t':
66 len += buf_addstr(buf, "\\t");
67 break;
68 default:
69 if ((*src == '\\') || (*src == '"'))
70 len += buf_addch(buf, '\\');
71 len += buf_addch(buf, src[0]);
72 }
73 }
74 return len;
75}
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:253
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:238
+ 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 += buf_addch(buf, '"');
91 len += escape_string(buf, str);
92 len += buf_addch(buf, '"');
93
94 return len;
95}
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 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}
#define CS_DUMP_HIDE_VALUE
Do not print the value of the config item.
Definition: dump.h:40
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
#define CS_DUMP_HIDE_NAME
Do not print the name of the config item.
Definition: dump.h:39
#define CS_DUMP_SHOW_DEFAULTS
Show the default value for the config item.
Definition: dump.h:41
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:45
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:195
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
char * data
Pointer to data.
Definition: buffer.h:35
Definition: set.h:64
const char * name
User-visible name.
Definition: set.h:65
intptr_t initial
Initial value.
Definition: set.h:67
const char * docs
One-liner description.
Definition: set.h:84
const char * name
Name of the type, e.g. "String".
Definition: set.h:98
union HashKey key
Key representing the data.
Definition: hash.h:46
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
void * data
User-supplied data.
Definition: hash.h:47
#define DT_SYNONYM
synonym for another variable
Definition: types.h:42
const char * strkey
String key.
Definition: hash.h:36
+ 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 **he_list = get_elem_list(cs);
173 if (!he_list)
174 return false; /* LCOV_EXCL_LINE */
175
176 bool result = true;
177
178 struct Buffer *value = buf_pool_get();
179 struct Buffer *initial = buf_pool_get();
180 struct Buffer *tmp = buf_pool_get();
181
182 for (size_t i = 0; he_list[i]; i++)
183 {
184 buf_reset(value);
185 buf_reset(initial);
186 he = 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 ((he->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->type) &&
213 (flags & CS_DUMP_HIDE_SENSITIVE) && !buf_is_empty(value))
214 {
215 buf_reset(value);
216 buf_addstr(value, "***");
217 }
218
219 if (((type == DT_PATH) || IS_MAILBOX(he->type)) && (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 buf_reset(tmp);
226 pretty_var(value->data, tmp);
227 buf_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->type)) && !(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 buf_reset(tmp);
248 pretty_var(initial->data, tmp);
249 buf_strcpy(initial, tmp->data);
250 }
251 }
252 }
253
254 dump_config_neo(cs, he, value, initial, flags, fp);
255 }
256
257 FREE(&he_list);
258 buf_pool_release(&value);
260 buf_pool_release(&tmp);
261
262 return result;
263}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:407
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
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
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:477
#define CS_DUMP_SHOW_SYNONYMS
Show synonyms and the config items they're linked to.
Definition: dump.h:43
#define CS_DUMP_SHOW_DISABLED
Show disabled config items, too.
Definition: dump.h:42
#define CS_DUMP_SHOW_DEPRECATED
Show config items that aren't used any more.
Definition: dump.h:44
#define CS_DUMP_NO_ESCAPING
Do not escape special chars, or quote the string.
Definition: dump.h:38
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:37
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:662
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:528
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define FREE(x)
Definition: memory.h:45
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:34
size_t dsize
Length of data.
Definition: buffer.h:37
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
The item stored in a Hash Table.
Definition: hash.h:44
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:70
#define IS_SENSITIVE(type)
Definition: types.h:60
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:45
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
#define DT_LONG
a number (long)
Definition: types.h:33
#define DT_BOOL
boolean option
Definition: types.h:30
#define IS_MAILBOX(type)
Definition: types.h:61
#define DT_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:78
#define DT_MAILBOX
Don't perform path expansions.
Definition: types.h:52
#define DT_PATH
a path to a file/directory
Definition: types.h:36
#define DT_STRING
a string
Definition: types.h:41
#define DT_DISABLED
Config item is disabled.
Definition: types.h:81
#define DT_NUMBER
a number
Definition: types.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function: