NeoMutt  2024-10-02-37-gfa9146
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
  • Pietro Cerutti
  • Dennis Schön

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

441{
442 if (!buf)
443 return;
444
445 char *p = buf, *q = buf;
446 size_t len;
447 enum UrlScheme scheme;
448 char tmp[PATH_MAX] = { 0 };
449
450 scheme = url_check_scheme(buf);
451
452 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
453 if ((scheme == U_IMAP) || (scheme == U_IMAPS))
454 {
455 imap_pretty_mailbox(buf, buflen, c_folder);
456 return;
457 }
458
459 if (scheme == U_NOTMUCH)
460 return;
461
462 /* if buf is an url, only collapse path component */
463 if (scheme != U_UNKNOWN)
464 {
465 p = strchr(buf, ':') + 1;
466 if (mutt_strn_equal(p, "//", 2))
467 q = strchr(p + 2, '/');
468 if (!q)
469 q = strchr(p, '\0');
470 p = q;
471 }
472
473 /* cleanup path */
474 if (strstr(p, "//") || strstr(p, "/./"))
475 {
476 /* first attempt to collapse the pathname, this is more
477 * lightweight than realpath() and doesn't resolve links */
478 while (*p)
479 {
480 if ((p[0] == '/') && (p[1] == '/'))
481 {
482 *q++ = '/';
483 p += 2;
484 }
485 else if ((p[0] == '/') && (p[1] == '.') && (p[2] == '/'))
486 {
487 *q++ = '/';
488 p += 3;
489 }
490 else
491 {
492 *q++ = *p++;
493 }
494 }
495 *q = '\0';
496 }
497 else if (strstr(p, "..") && ((scheme == U_UNKNOWN) || (scheme == U_FILE)) &&
498 realpath(p, tmp))
499 {
500 mutt_str_copy(p, tmp, buflen - (p - buf));
501 }
502
503 if ((len = mutt_str_startswith(buf, c_folder)) && (buf[len] == '/'))
504 {
505 *buf++ = '=';
506 memmove(buf, buf + len, mutt_str_len(buf + len) + 1);
507 }
508 else if ((len = mutt_str_startswith(buf, HomeDir)) && (buf[len] == '/'))
509 {
510 *buf++ = '~';
511 memmove(buf, buf + len - 1, mutt_str_len(buf + len - 1) + 1);
512 }
513}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
char * HomeDir
User's home directory.
Definition: globals.c:37
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:585
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:425
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:496
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:581
#define PATH_MAX
Definition: mutt.h:42
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition: url.c:226
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 48 of file dump.c.

49{
50 if (!buf || !src)
51 return 0;
52
53 size_t len = 0;
54 for (; *src; src++)
55 {
56 switch (*src)
57 {
58 case '\007':
59 len += buf_addstr(buf, "\\g");
60 break;
61 case '\n':
62 len += buf_addstr(buf, "\\n");
63 break;
64 case '\r':
65 len += buf_addstr(buf, "\\r");
66 break;
67 case '\t':
68 len += buf_addstr(buf, "\\t");
69 break;
70 default:
71 if ((*src == '\\') || (*src == '"'))
72 len += buf_addch(buf, '\\');
73 len += buf_addch(buf, src[0]);
74 }
75 }
76 return len;
77}
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
+ 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 85 of file dump.c.

86{
87 if (!buf || !str)
88 return 0;
89
90 int len = 0;
91
92 len += buf_addch(buf, '"');
93 len += escape_string(buf, str);
94 len += buf_addch(buf, '"');
95
96 return len;
97}
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:48
+ 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 108 of file dump.c.

110{
111 if (!he || !value || !fp)
112 return;
113
114 const char *name = he->key.strkey;
115
116 if ((flags & CS_DUMP_ONLY_CHANGED) &&
117 (!initial || mutt_str_equal(value->data, initial->data)))
118 {
119 return;
120 }
121
122 if (he->type == DT_SYNONYM)
123 {
124 const struct ConfigDef *cdef = he->data;
125 const char *syn = (const char *) cdef->initial;
126 fprintf(fp, "# synonym: %s -> %s\n", name, syn);
127 return;
128 }
129
130 if (flags & CS_DUMP_SHOW_DOCS)
131 {
132 const struct ConfigDef *cdef = he->data;
133 fprintf(fp, "# %s\n", cdef->docs);
134 }
135
136 bool show_name = !(flags & CS_DUMP_HIDE_NAME);
137 bool show_value = !(flags & CS_DUMP_HIDE_VALUE);
138
139 if (show_name && show_value)
140 fprintf(fp, "set ");
141 if (show_name)
142 fprintf(fp, "%s", name);
143 if (show_name && show_value)
144 fprintf(fp, " = ");
145 if (show_value)
146 fprintf(fp, "%s", value->data);
147 if (show_name || show_value)
148 fprintf(fp, "\n");
149
150 if (flags & CS_DUMP_SHOW_DEFAULTS)
151 {
152 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
153 if (cst)
154 fprintf(fp, "# %s %s %s\n", cst->name, name, value->data);
155 }
156
157 if (flags & CS_DUMP_SHOW_DOCS)
158 fprintf(fp, "\n");
159}
#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:198
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
char * data
Pointer to data.
Definition: buffer.h:37
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:45
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:44
void * data
User-supplied data.
Definition: hash.h:46
@ DT_SYNONYM
synonym for another variable
Definition: types.h:46
const char * strkey
String key.
Definition: hash.h:35
+ 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 167 of file dump.c.

168{
169 if (!cs)
170 return false;
171
172 struct HashElem *he = NULL;
173
174 struct HashElem **he_list = get_elem_list(cs);
175 if (!he_list)
176 return false; /* LCOV_EXCL_LINE */
177
178 bool result = true;
179
180 struct Buffer *value = buf_pool_get();
181 struct Buffer *initial = buf_pool_get();
182 struct Buffer *tmp = buf_pool_get();
183
184 for (size_t i = 0; he_list[i]; i++)
185 {
186 buf_reset(value);
187 buf_reset(initial);
188 he = he_list[i];
189 const int type = DTYPE(he->type);
190
191 if ((type == DT_SYNONYM) && !(flags & CS_DUMP_SHOW_SYNONYMS))
192 continue;
193
194 if ((he->type & D_INTERNAL_DEPRECATED) && !(flags & CS_DUMP_SHOW_DEPRECATED))
195 continue;
196
197 if (type != DT_SYNONYM)
198 {
199 /* If necessary, get the current value */
200 if ((flags & CS_DUMP_ONLY_CHANGED) || !(flags & CS_DUMP_HIDE_VALUE) ||
201 (flags & CS_DUMP_SHOW_DEFAULTS))
202 {
203 int rc = cs_he_string_get(cs, he, value);
204 if (CSR_RESULT(rc) != CSR_SUCCESS)
205 {
206 result = false; /* LCOV_EXCL_LINE */
207 break; /* LCOV_EXCL_LINE */
208 }
209
210 const struct ConfigDef *cdef = he->data;
211 if ((type == DT_STRING) && (cdef->type & D_SENSITIVE) &&
212 (flags & CS_DUMP_HIDE_SENSITIVE) && !buf_is_empty(value))
213 {
214 buf_reset(value);
215 buf_addstr(value, "***");
216 }
217
218 if (((type == DT_PATH) || IS_MAILBOX(he->type)) && (value->data[0] == '/'))
219 mutt_pretty_mailbox(value->data, value->dsize);
220
221 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
222 (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
223 {
224 buf_reset(tmp);
225 pretty_var(value->data, tmp);
226 buf_strcpy(value, tmp->data);
227 }
228 }
229
230 /* If necessary, get the default value */
232 {
233 int rc = cs_he_initial_get(cs, he, initial);
234 if (CSR_RESULT(rc) != CSR_SUCCESS)
235 {
236 result = false; /* LCOV_EXCL_LINE */
237 break; /* LCOV_EXCL_LINE */
238 }
239
240 if (((type == DT_PATH) || IS_MAILBOX(he->type)) && !(he->type & D_STRING_MAILBOX))
241 mutt_pretty_mailbox(initial->data, initial->dsize);
242
243 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
244 (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
245 {
246 buf_reset(tmp);
247 pretty_var(initial->data, tmp);
248 buf_strcpy(initial, tmp->data);
249 }
250 }
251 }
252
253 dump_config_neo(cs, he, value, initial, flags, fp);
254 }
255
256 FREE(&he_list);
257 buf_pool_release(&value);
259 buf_pool_release(&tmp);
260
261 return result;
262}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:85
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:108
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:440
#define CS_DUMP_SHOW_SYNONYMS
Show synonyms and the config items they're linked to.
Definition: dump.h:43
#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:663
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:529
#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:36
size_t dsize
Length of data.
Definition: buffer.h:39
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
The item stored in a Hash Table.
Definition: hash.h:43
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:79
#define IS_MAILBOX(flags)
Definition: types.h:122
#define DTYPE(t)
Definition: types.h:50
#define D_INTERNAL_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:88
@ DT_NUMBER
a number
Definition: types.h:39
@ DT_BOOL
boolean option
Definition: types.h:32
@ DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:41
@ DT_STRING
a string
Definition: types.h:45
@ DT_LONG
a number (long)
Definition: types.h:36
@ DT_PATH
a path to a file/directory
Definition: types.h:40
#define D_STRING_MAILBOX
Don't perform path expansions.
Definition: types.h:98
#define D_SENSITIVE
Contains sensitive value, e.g. password.
Definition: types.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function: