NeoMutt  2019-11-11
Teaching an old dog new tricks
DOXYGEN
rfc3676.c File Reference

RFC3676 Format Flowed routines. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "email/lib.h"
#include "curs_lib.h"
#include "globals.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "state.h"
+ Include dependency graph for rfc3676.c:

Go to the source code of this file.

Data Structures

struct  FlowedState
 State of a Format-Flowed line of text. More...
 

Macros

#define FLOWED_MAX   72
 

Functions

static int get_quote_level (const char *line)
 Get the quote level of a line. More...
 
static int space_quotes (struct State *s)
 Should we add spaces between quote levels. More...
 
static bool add_quote_suffix (struct State *s, int ql)
 Should we add a trailing space to quotes. More...
 
static size_t print_indent (int ql, struct State *s, int add_suffix)
 Print indented text. More...
 
static void flush_par (struct State *s, struct FlowedState *fst)
 Write out the paragraph. More...
 
static int quote_width (struct State *s, int ql)
 Calculate the paragraph width based upon the quote level. More...
 
static void print_flowed_line (char *line, struct State *s, int ql, struct FlowedState *fst, bool term)
 Print a format-flowed line. More...
 
static void print_fixed_line (const char *line, struct State *s, int ql, struct FlowedState *fst)
 Print a fixed format line. More...
 
int rfc3676_handler (struct Body *a, struct State *s)
 Body handler implementing RFC3676 for format=flowed - Implements handler_t. More...
 
static void rfc3676_space_stuff (struct Email *e, bool unstuff)
 Perform required RFC3676 space stuffing. More...
 
void mutt_rfc3676_space_stuff (struct Email *e)
 Perform RFC3676 space stuffing on an Email. More...
 
void mutt_rfc3676_space_unstuff (struct Email *e)
 Remove RFC3676 space stuffing. More...
 

Variables

bool C_ReflowSpaceQuotes
 Config: Insert spaces into reply quotes for 'format=flowed' messages. More...
 
short C_ReflowWrap
 Config: Maximum paragraph width for reformatting 'format=flowed' text. More...
 

Detailed Description

RFC3676 Format Flowed routines.

Authors
  • Andreas Krennmair
  • Peter J. Holzer
  • Rocco Rutte
  • Michael R. Elkins

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 rfc3676.c.

Macro Definition Documentation

◆ FLOWED_MAX

#define FLOWED_MAX   72

Definition at line 50 of file rfc3676.c.

Function Documentation

◆ get_quote_level()

static int get_quote_level ( const char *  line)
static

Get the quote level of a line.

Parameters
lineText to examine
Return values
numQuote level

Definition at line 67 of file rfc3676.c.

68 {
69  int quoted = 0;
70  const char *p = line;
71 
72  while (p && (*p == '>'))
73  {
74  quoted++;
75  p++;
76  }
77 
78  return quoted;
79 }
const char * line
Definition: common.c:36
+ Here is the caller graph for this function:

◆ space_quotes()

static int space_quotes ( struct State s)
static

Should we add spaces between quote levels.

Parameters
sState to use
Return values
trueIf spaces should be added

Determines whether to add spacing between/after each quote level: >>>foo becomes > > > foo

Definition at line 91 of file rfc3676.c.

92 {
93  /* Allow quote spacing in the pager even for C_TextFlowed,
94  * but obviously not when replying. */
95  if (C_TextFlowed && (s->flags & MUTT_REPLYING))
96  return 0;
97 
98  return C_ReflowSpaceQuotes;
99 }
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:266
#define MUTT_REPLYING
Are we replying?
Definition: state.h:38
bool C_ReflowSpaceQuotes
Config: Insert spaces into reply quotes for &#39;format=flowed&#39; messages.
Definition: rfc3676.c:47
+ Here is the caller graph for this function:

◆ add_quote_suffix()

static bool add_quote_suffix ( struct State s,
int  ql 
)
static

Should we add a trailing space to quotes.

Parameters
sState to use
qlQuote level
Return values
trueIf spaces should be added

Determines whether to add a trailing space to quotes: >>> foo as opposed to >>>foo

Definition at line 112 of file rfc3676.c.

113 {
114  if (s->flags & MUTT_REPLYING)
115  return false;
116 
117  if (space_quotes(s))
118  return false;
119 
120  if (!ql && !s->prefix)
121  return false;
122 
123  /* The prefix will add its own space */
124  if (!C_TextFlowed && !ql && s->prefix)
125  return false;
126 
127  return true;
128 }
static int space_quotes(struct State *s)
Should we add spaces between quote levels.
Definition: rfc3676.c:91
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:266
#define MUTT_REPLYING
Are we replying?
Definition: state.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_indent()

static size_t print_indent ( int  ql,
struct State s,
int  add_suffix 
)
static

Print indented text.

Parameters
qlQuote level
sState to work with
add_suffixIf true, write a trailing space character
Return values
numNumber of characters written

Definition at line 137 of file rfc3676.c.

138 {
139  size_t wid = 0;
140 
141  if (s->prefix)
142  {
143  /* use given prefix only for format=fixed replies to format=flowed,
144  * for format=flowed replies to format=flowed, use '>' indentation */
145  if (C_TextFlowed)
146  ql++;
147  else
148  {
149  state_puts(s, s->prefix);
150  wid = mutt_strwidth(s->prefix);
151  }
152  }
153  for (int i = 0; i < ql; i++)
154  {
155  state_putc(s, '>');
156  if (space_quotes(s))
157  state_putc(s, ' ');
158  }
159  if (add_suffix)
160  state_putc(s, ' ');
161 
162  if (space_quotes(s))
163  ql *= 2;
164 
165  return ql + add_suffix + wid;
166 }
#define state_puts(STATE, STR)
Definition: state.h:55
static int space_quotes(struct State *s)
Should we add spaces between quote levels.
Definition: rfc3676.c:91
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1287
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:266
#define state_putc(STATE, STR)
Definition: state.h:56
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ flush_par()

static void flush_par ( struct State s,
struct FlowedState fst 
)
static

Write out the paragraph.

Parameters
sState to work with
fstThe state of the flowed text

Definition at line 173 of file rfc3676.c.

174 {
175  if (fst->width > 0)
176  {
177  state_putc(s, '\n');
178  fst->width = 0;
179  }
180  fst->spaces = 0;
181 }
size_t spaces
Definition: rfc3676.c:58
size_t width
Definition: rfc3676.c:57
#define state_putc(STATE, STR)
Definition: state.h:56
+ Here is the caller graph for this function:

◆ quote_width()

static int quote_width ( struct State s,
int  ql 
)
static

Calculate the paragraph width based upon the quote level.

Parameters
sState to use
qlQuote level
Return values
numParagraph width

The start of a quoted line will be ">>> ", so we need to subtract the space required for the prefix from the terminal width.

Definition at line 192 of file rfc3676.c.

193 {
194  const int screen_width = (s->flags & MUTT_DISPLAY) ? s->wraplen : 80;
195  int width = mutt_window_wrap_cols(screen_width, C_ReflowWrap);
196  if (C_TextFlowed && (s->flags & MUTT_REPLYING))
197  {
198  /* When replying, force a wrap at FLOWED_MAX to comply with RFC3676
199  * guidelines */
200  if (width > FLOWED_MAX)
201  width = FLOWED_MAX;
202  ql++; /* When replying, we will add an additional quote level */
203  }
204  /* adjust the paragraph width subtracting the number of prefix chars */
205  width -= space_quotes(s) ? ql * 2 : ql;
206  /* When displaying (not replying), there may be a space between the prefix
207  * string and the paragraph */
208  if (add_quote_suffix(s, ql))
209  width--;
210  /* failsafe for really long quotes */
211  if (width <= 0)
212  width = FLOWED_MAX; /* arbitrary, since the line will wrap */
213  return width;
214 }
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
static bool add_quote_suffix(struct State *s, int ql)
Should we add a trailing space to quotes.
Definition: rfc3676.c:112
static int space_quotes(struct State *s)
Should we add spaces between quote levels.
Definition: rfc3676.c:91
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
int wraplen
Width to wrap lines to (when flags & MUTT_DISPLAY)
Definition: state.h:50
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:351
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:266
#define FLOWED_MAX
Definition: rfc3676.c:50
#define MUTT_REPLYING
Are we replying?
Definition: state.h:38
short C_ReflowWrap
Config: Maximum paragraph width for reformatting &#39;format=flowed&#39; text.
Definition: rfc3676.c:48
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_flowed_line()

static void print_flowed_line ( char *  line,
struct State s,
int  ql,
struct FlowedState fst,
bool  term 
)
static

Print a format-flowed line.

Parameters
lineText to print
sState to work with
qlQuote level
fstThe state of the flowed text
termIf true, terminate with a new line

Definition at line 224 of file rfc3676.c.

226 {
227  size_t width, w, words = 0;
228  char *p = NULL;
229  char last;
230 
231  if (!line || !*line)
232  {
233  /* flush current paragraph (if any) first */
234  flush_par(s, fst);
235  print_indent(ql, s, 0);
236  state_putc(s, '\n');
237  return;
238  }
239 
240  width = quote_width(s, ql);
241  last = line[mutt_str_strlen(line) - 1];
242 
243  mutt_debug(LL_DEBUG5, "f=f: line [%s], width = %ld, spaces = %lu\n", line,
244  (long) width, fst->spaces);
245 
246  for (words = 0; (p = strsep(&line, " "));)
247  {
248  mutt_debug(LL_DEBUG5, "f=f: word [%s], width: %lu, remaining = [%s]\n", p,
249  fst->width, line);
250 
251  /* remember number of spaces */
252  if (!*p)
253  {
254  mutt_debug(LL_DEBUG3, "f=f: additional space\n");
255  fst->spaces++;
256  continue;
257  }
258  /* there's exactly one space prior to every but the first word */
259  if (words)
260  fst->spaces++;
261 
262  w = mutt_strwidth(p);
263  /* see if we need to break the line but make sure the first word is put on
264  * the line regardless; if for DelSp=yes only one trailing space is used,
265  * we probably have a long word that we should break within (we leave that
266  * up to the pager or user) */
267  if (!(!fst->spaces && fst->delsp && (last != ' ')) && (w < width) &&
268  (w + fst->width + fst->spaces > width))
269  {
270  mutt_debug(LL_DEBUG3, "f=f: break line at %lu, %lu spaces left\n",
271  fst->width, fst->spaces);
272  /* only honor trailing spaces for format=flowed replies */
273  if (C_TextFlowed)
274  for (; fst->spaces; fst->spaces--)
275  state_putc(s, ' ');
276  state_putc(s, '\n');
277  fst->width = 0;
278  fst->spaces = 0;
279  words = 0;
280  }
281 
282  if (!words && !fst->width)
283  fst->width = print_indent(ql, s, add_quote_suffix(s, ql));
284  fst->width += w + fst->spaces;
285  for (; fst->spaces; fst->spaces--)
286  state_putc(s, ' ');
287  state_puts(s, p);
288  words++;
289  }
290 
291  if (term)
292  flush_par(s, fst);
293 }
#define state_puts(STATE, STR)
Definition: state.h:55
static bool add_quote_suffix(struct State *s, int ql)
Should we add a trailing space to quotes.
Definition: rfc3676.c:112
static int quote_width(struct State *s, int ql)
Calculate the paragraph width based upon the quote level.
Definition: rfc3676.c:192
size_t spaces
Definition: rfc3676.c:58
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
const char * line
Definition: common.c:36
static size_t print_indent(int ql, struct State *s, int add_suffix)
Print indented text.
Definition: rfc3676.c:137
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1287
size_t width
Definition: rfc3676.c:57
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:266
static void flush_par(struct State *s, struct FlowedState *fst)
Write out the paragraph.
Definition: rfc3676.c:173
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define state_putc(STATE, STR)
Definition: state.h:56
Log at debug level 5.
Definition: logging.h:60
bool delsp
Definition: rfc3676.c:59
Log at debug level 3.
Definition: logging.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_fixed_line()

static void print_fixed_line ( const char *  line,
struct State s,
int  ql,
struct FlowedState fst 
)
static

Print a fixed format line.

Parameters
lineText to print
sState to work with
qlQuote level
fstThe state of the flowed text

Definition at line 302 of file rfc3676.c.

303 {
304  print_indent(ql, s, add_quote_suffix(s, ql));
305  if (line && *line)
306  state_puts(s, line);
307  state_putc(s, '\n');
308 
309  fst->width = 0;
310  fst->spaces = 0;
311 }
#define state_puts(STATE, STR)
Definition: state.h:55
static bool add_quote_suffix(struct State *s, int ql)
Should we add a trailing space to quotes.
Definition: rfc3676.c:112
size_t spaces
Definition: rfc3676.c:58
const char * line
Definition: common.c:36
static size_t print_indent(int ql, struct State *s, int add_suffix)
Print indented text.
Definition: rfc3676.c:137
size_t width
Definition: rfc3676.c:57
#define state_putc(STATE, STR)
Definition: state.h:56
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rfc3676_handler()

int rfc3676_handler ( struct Body a,
struct State s 
)

Body handler implementing RFC3676 for format=flowed - Implements handler_t.

Return values
0Always

Definition at line 317 of file rfc3676.c.

318 {
319  char *buf = NULL;
320  unsigned int quotelevel = 0;
321  bool delsp = false;
322  size_t sz = 0;
323  struct FlowedState fst = { 0 };
324 
325  /* respect DelSp of RFC3676 only with f=f parts */
326  char *t = mutt_param_get(&a->parameter, "delsp");
327  if (t)
328  {
329  delsp = (mutt_str_strcasecmp(t, "yes") == 0);
330  t = NULL;
331  fst.delsp = true;
332  }
333 
334  mutt_debug(LL_DEBUG3, "f=f: DelSp: %s\n", delsp ? "yes" : "no");
335 
336  while ((buf = mutt_file_read_line(buf, &sz, s->fp_in, NULL, 0)))
337  {
338  const size_t buf_len = mutt_str_strlen(buf);
339  const unsigned int newql = get_quote_level(buf);
340 
341  /* end flowed paragraph (if we're within one) if quoting level
342  * changes (should not but can happen, see RFC3676, sec. 4.5.) */
343  if (newql != quotelevel)
344  flush_par(s, &fst);
345 
346  quotelevel = newql;
347  int buf_off = newql;
348 
349  /* respect sender's space-stuffing by removing one leading space */
350  if (buf[buf_off] == ' ')
351  buf_off++;
352 
353  /* test for signature separator */
354  const unsigned int sigsep = (mutt_str_strcmp(buf + buf_off, "-- ") == 0);
355 
356  /* a fixed line either has no trailing space or is the
357  * signature separator */
358  const bool fixed = (buf_len == buf_off) || (buf[buf_len - 1] != ' ') || sigsep;
359 
360  /* print fixed-and-standalone, fixed-and-empty and sigsep lines as
361  * fixed lines */
362  if ((fixed && ((fst.width == 0) || (buf_len == 0))) || sigsep)
363  {
364  /* if we're within a flowed paragraph, terminate it */
365  flush_par(s, &fst);
366  print_fixed_line(buf + buf_off, s, quotelevel, &fst);
367  continue;
368  }
369 
370  /* for DelSp=yes, we need to strip one SP prior to CRLF on flowed lines */
371  if (delsp && !fixed)
372  buf[buf_len - 1] = '\0';
373 
374  print_flowed_line(buf + buf_off, s, quotelevel, &fst, fixed);
375  }
376 
377  flush_par(s, &fst);
378 
379  FREE(&buf);
380  return 0;
381 }
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:664
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
FILE * fp_in
File to read from.
Definition: state.h:46
static int get_quote_level(const char *line)
Get the quote level of a line.
Definition: rfc3676.c:67
static void print_fixed_line(const char *line, struct State *s, int ql, struct FlowedState *fst)
Print a fixed format line.
Definition: rfc3676.c:302
size_t width
Definition: rfc3676.c:57
State of a Format-Flowed line of text.
Definition: rfc3676.c:55
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define FREE(x)
Definition: memory.h:40
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
static void flush_par(struct State *s, struct FlowedState *fst)
Write out the paragraph.
Definition: rfc3676.c:173
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static void print_flowed_line(char *line, struct State *s, int ql, struct FlowedState *fst, bool term)
Print a format-flowed line.
Definition: rfc3676.c:224
bool delsp
Definition: rfc3676.c:59
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
Log at debug level 3.
Definition: logging.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rfc3676_space_stuff()

static void rfc3676_space_stuff ( struct Email e,
bool  unstuff 
)
static

Perform required RFC3676 space stuffing.

Parameters
eEmail
unstuffIf true, remove space stuffing

Space stuffing means that we have to add leading spaces to certain lines:

  • lines starting with a space
  • lines starting with 'From '

Care is taken to preserve the e->content->filename, as mutt -i -E can directly edit a passed in filename.

Definition at line 396 of file rfc3676.c.

397 {
398  FILE *fp_out = NULL;
399  char *buf = NULL;
400  size_t blen = 0;
401 
402  struct Buffer *tmpfile = mutt_buffer_pool_get();
403 
404  FILE *fp_in = mutt_file_fopen(e->content->filename, "r");
405  if (!fp_in)
406  goto bail;
407 
408  mutt_buffer_mktemp(tmpfile);
409  fp_out = mutt_file_fopen(mutt_b2s(tmpfile), "w+");
410  if (!fp_out)
411  goto bail;
412 
413  while ((buf = mutt_file_read_line(buf, &blen, fp_in, NULL, 0)) != NULL)
414  {
415  if (unstuff)
416  {
417  if (buf[0] == ' ')
418  fputs(buf + 1, fp_out);
419  else
420  fputs(buf, fp_out);
421  }
422  else
423  {
424  if ((buf[0] == ' ') || mutt_str_startswith(buf, "From ", CASE_MATCH))
425  fputc(' ', fp_out);
426  fputs(buf, fp_out);
427  }
428  fputc('\n', fp_out);
429  }
430  FREE(&buf);
431  mutt_file_fclose(&fp_in);
432  mutt_file_fclose(&fp_out);
434 
435  fp_in = mutt_file_fopen(mutt_b2s(tmpfile), "r");
436  if (!fp_in)
437  goto bail;
438 
439  if ((truncate(e->content->filename, 0) == -1) ||
440  ((fp_out = mutt_file_fopen(e->content->filename, "a")) == NULL))
441  {
443  goto bail;
444  }
445 
446  mutt_file_copy_stream(fp_in, fp_out);
447  mutt_file_fclose(&fp_in);
448  mutt_file_fclose(&fp_out);
450  unlink(mutt_b2s(tmpfile));
451  mutt_buffer_pool_release(&tmpfile);
452  return;
453 
454 bail:
455  mutt_file_fclose(&fp_in);
456  mutt_file_fclose(&fp_out);
457  mutt_buffer_pool_release(&tmpfile);
458 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:79
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
#define mutt_perror(...)
Definition: logging.h:85
void mutt_file_set_mtime(const char *from, const char *to)
Set the modification time of one file from another.
Definition: file.c:994
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
struct Body * content
List of MIME parts.
Definition: email.h:90
String manipulation buffer.
Definition: buffer.h:33
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, int flags)
Read a line from a file.
Definition: file.c:664
Match case when comparing strings.
Definition: string2.h:67
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
#define mutt_b2s(buf)
Definition: buffer.h:41
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
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:270
#define FREE(x)
Definition: memory.h:40
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_rfc3676_space_stuff()

void mutt_rfc3676_space_stuff ( struct Email e)

Perform RFC3676 space stuffing on an Email.

Parameters
eEmail

Note: we don't check the option C_TextFlowed because we want to stuff based the actual content type. The option only decides whether to set format=flowed on new messages.

Definition at line 468 of file rfc3676.c.

469 {
470  if (!e || !e->content || !e->content->filename)
471  return;
472 
473  if ((e->content->type == TYPE_TEXT) &&
474  (mutt_str_strcasecmp("plain", e->content->subtype) == 0))
475  {
476  const char *format = mutt_param_get(&e->content->parameter, "format");
477  if (mutt_str_strcasecmp("flowed", format) == 0)
478  rfc3676_space_stuff(e, false);
479  }
480 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Body * content
List of MIME parts.
Definition: email.h:90
char * subtype
content-type subtype
Definition: body.h:37
Type: &#39;text/*&#39;.
Definition: mime.h:38
unsigned int type
content-type primary type
Definition: body.h:65
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
static void rfc3676_space_stuff(struct Email *e, bool unstuff)
Perform required RFC3676 space stuffing.
Definition: rfc3676.c:396
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_rfc3676_space_unstuff()

void mutt_rfc3676_space_unstuff ( struct Email e)

Remove RFC3676 space stuffing.

Parameters
eEmail

Definition at line 486 of file rfc3676.c.

487 {
488  if (!e || !e->content || !e->content->filename)
489  return;
490 
491  if ((e->content->type == TYPE_TEXT) &&
492  !mutt_str_strcasecmp("plain", e->content->subtype))
493  {
494  const char *format = mutt_param_get(&e->content->parameter, "format");
495  if (mutt_str_strcasecmp("flowed", format) == 0)
496  rfc3676_space_stuff(e, true);
497  }
498 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Body * content
List of MIME parts.
Definition: email.h:90
char * subtype
content-type subtype
Definition: body.h:37
Type: &#39;text/*&#39;.
Definition: mime.h:38
unsigned int type
content-type primary type
Definition: body.h:65
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
static void rfc3676_space_stuff(struct Email *e, bool unstuff)
Perform required RFC3676 space stuffing.
Definition: rfc3676.c:396
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_ReflowSpaceQuotes

bool C_ReflowSpaceQuotes

Config: Insert spaces into reply quotes for 'format=flowed' messages.

Definition at line 47 of file rfc3676.c.

◆ C_ReflowWrap

short C_ReflowWrap

Config: Maximum paragraph width for reformatting 'format=flowed' text.

Definition at line 48 of file rfc3676.c.