X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=rfc3676.c;h=c194540ef12c1848c6191c287cac3f10c91ad523;hp=9efa39d364d32171ef12583fe8b670d7bd46fae4;hb=d5d56308b49c3f157a17125415312f0c13e1e25b;hpb=618ceafdc9564dbb8f3bf45c3869297a1d5a3320 diff --git a/rfc3676.c b/rfc3676.c index 9efa39d..c194540 100644 --- a/rfc3676.c +++ b/rfc3676.c @@ -20,16 +20,18 @@ #include #include +#include +#include +#include +#include +#include + #include "mutt.h" #include "mutt_curses.h" -#include "ascii.h" #include "handler.h" #include "state.h" #include "lib.h" -#include "lib/mem.h" -#include "lib/intl.h" -#include "lib/str.h" #include "lib/debug.h" #define FLOWED_MAX 77 @@ -42,17 +44,15 @@ static int get_quote_level (char *line) return quoted; } -static void print_flowed_line (char *line, STATE * s, - int ql, int delsp, - int* spaces, int space_len) { +static void print_flowed_line (char *line, STATE * s, int ql) { int width; char *pos, *oldpos; - int len = str_len (line); + int len = m_strlen(line); int i; if (MaxLineLength > 0) { width = MaxLineLength - WrapMargin - ql - 1; - if (option (OPTSTUFFQUOTED)) + if (!(s->flags & M_REPLYING) && option (OPTSTUFFQUOTED)) --width; if (width < 0) width = MaxLineLength; @@ -63,18 +63,18 @@ static void print_flowed_line (char *line, STATE * s, else width = COLS - WrapMargin - ql - 1; - if (option (OPTSTUFFQUOTED)) + if (!(s->flags & M_REPLYING) && option (OPTSTUFFQUOTED)) --width; if (width < 0) width = COLS; } - if (str_len (line) == 0) { - if (option (OPTQUOTEEMPTY)) { + if (m_strlen(line) == 0) { + if (!(s->flags & M_REPLYING) || option (OPTQUOTEEMPTY)) { if (s->prefix) state_puts(s->prefix,s); for (i=0;i',s); - if (option(OPTSTUFFQUOTED)) + if (!(s->flags & M_REPLYING) && option(OPTSTUFFQUOTED)) state_putc(' ',s); } state_putc('\n',s); @@ -123,24 +123,10 @@ static void print_flowed_line (char *line, STATE * s, for (i = 0; i < ql; ++i) state_putc ('>', s); - if (option (OPTSTUFFQUOTED) && (ql > 0 || s->prefix)) + if (!(s->flags & M_REPLYING) && option (OPTSTUFFQUOTED) && + (ql > 0 || s->prefix)) state_putc (' ', s); - - if (delsp && spaces && space_len > 0) { - /* here, we need to character-wise step through the line - * to eliminate all spaces which were trailing due to DelSp */ - for (i = 0; i < str_len (oldpos); i++) { - if (oldpos[i] == ' ' && spaces[&(oldpos[i])-line] != 0) { - debug_print (4, ("f=f: DelSp: spaces[%d] forces space removal\n", - &(oldpos[i])-line)); - continue; - } - /* print space at oldpos[i] if it was non-trailing */ - state_putc (oldpos[i], s); - } - } else - /* for no DelSp, just do whole line as per usual */ - state_puts (oldpos, s); + state_puts (oldpos, s); /* fprintf(stderr,"print_flowed_line: `%s'\n",oldpos); */ if (pos < line + len) state_putc (' ', s); @@ -152,24 +138,26 @@ static void print_flowed_line (char *line, STATE * s, int rfc3676_handler (BODY * a, STATE * s) { int bytes = a->length; char buf[LONG_STRING]; - char *curline = str_dup (""); + char *curline = p_new(char, 1); char *t = NULL; - unsigned int curline_len = 1, space_len = 1, + unsigned int curline_len = 1, quotelevel = 0, newql = 0; int buf_off, buf_len; - int delsp = 0; - int* spaces = NULL; + int delsp = 0, fixed = 0; + + *curline='\0'; /* respect DelSP of RfC3676 only with f=f parts */ if ((t = (char*) mutt_get_parameter ("delsp", a->parameter))) { - delsp = str_len (t) == 3 && ascii_strncasecmp (t, "yes", 3) == 0; + delsp = m_strlen(t) == 3 && ascii_strncasecmp (t, "yes", 3) == 0; t = NULL; } debug_print (2, ("f=f: DelSp: %s\n", delsp ? "yes" : "no")); while (bytes > 0 && fgets (buf, sizeof (buf), s->fpin)) { - buf_len = str_len (buf); + + buf_len = m_strlen(buf); bytes -= buf_len; newql = get_quote_level (buf); @@ -178,10 +166,9 @@ int rfc3676_handler (BODY * a, STATE * s) { * but has to be handled - see RFC 3676, sec. 4.5. */ if (newql != quotelevel && curline && *curline) { - print_flowed_line (curline, s, quotelevel, delsp, spaces, space_len); + print_flowed_line (curline, s, quotelevel); *curline = '\0'; curline_len = 1; - space_len = 0; } quotelevel = newql; @@ -190,88 +177,100 @@ int rfc3676_handler (BODY * a, STATE * s) { * possibly a change in quoting level. But that's better than not * displaying it at all. */ - if ((t = strrchr (buf, '\n')) || (t = strrchr (buf, '\r'))) { + if ((t = strrchr (buf, '\r')) || (t = strrchr (buf, '\n'))) { *t = '\0'; buf_len = t - buf; } + buf_off = newql; /* respect space-stuffing */ if (buf[buf_off] == ' ') buf_off++; + /* for DelSp=yes, we need to strip one SP prior to CRLF + * which may make the line look like fixed although it wasn't + * so keep this in mind for later processing */ + fixed = buf_len == 0 || buf[buf_len - 1] != ' ' || + (strcmp(buf + buf_off, "-- ") == 0); + + if (delsp && buf_len >= 1 && buf[buf_len-1] == ' ') + buf[--buf_len] = '\0'; + + /* we're here when last space removed 'cause of DelSp was + * the last space and there isn't more -> done */ + if ((buf_len - buf_off) < 0) { + print_flowed_line (curline, s, quotelevel); + *curline = '\0'; + curline_len = 1; + continue; + } + /* signature separator also flushes the previous paragraph */ if (strcmp(buf + buf_off, "-- ") == 0 && curline && *curline) { - print_flowed_line (curline, s, quotelevel, delsp, spaces, space_len); + print_flowed_line (curline, s, quotelevel); *curline = '\0'; curline_len = 1; - space_len = 0; } - mem_realloc (&curline, curline_len + buf_len - buf_off); - mem_realloc (&spaces, (curline_len + buf_len - buf_off)*sizeof (int)); + p_realloc(&curline, curline_len + buf_len - buf_off); strcpy (curline + curline_len - 1, buf + buf_off); - memset (&spaces[space_len], 0, (buf_len - buf_off)*sizeof (int)); curline_len += buf_len - buf_off; - space_len += buf_len - buf_off; /* if this was a fixed line the paragraph is finished */ - if (buf_len == 0 || buf[buf_len - 1] != ' ' || strcmp(buf + buf_off, "-- ") == 0) { - print_flowed_line (curline, s, quotelevel, delsp, spaces, space_len); + if (fixed) { + print_flowed_line (curline, s, quotelevel); *curline = '\0'; curline_len = 1; - space_len = 0; - } else { - /* if last line we appended had a space and we have DelSp=yes, - * get a 1 into spaces array at proper position so that - * print_flowed_line() can handle it; don't kill the space - * right here 'cause we maybe need soft linebreaks to search for break - */ - if (delsp && curline && *curline && curline_len-2 >= 0 && - curline[curline_len-2] == ' ') { - debug_print (4, ("f=f: DelSp: marking spaces[%d] for later removal\n", - curline_len-2)); - spaces[curline_len-2] = 1; - } } } - mem_free (&spaces); - mem_free (&curline); + p_delete(&curline); return (0); } -void rfc3676_quote_line (STATE* s, char* dst, size_t dstlen, - const char* line) { - char quote[SHORT_STRING]; - int offset = 0, i = 0, count = 0; - regmatch_t pmatch[1]; +void rfc3676_space_stuff (HEADER* hdr) { +#if DEBUG + int lc = 0; + size_t len = 0; + unsigned char c = '\0'; +#endif + FILE* in = NULL, *out = NULL; + char buf[LONG_STRING]; + char tmpfile[_POSIX_PATH_MAX]; - quote[0] = '\0'; + if (!hdr || !hdr->content || !hdr->content->filename) + return; - while (regexec ((regex_t *) QuoteRegexp.rx, &line[offset], - 1, pmatch, 0) == 0) - offset += pmatch->rm_eo; + debug_print (2, ("f=f: postprocess %s\n", hdr->content->filename)); + if ((in = safe_fopen (hdr->content->filename, "r")) == NULL) + return; + mutt_mktemp (tmpfile); + if ((out = safe_fopen (tmpfile, "w+")) == NULL) { + fclose (in); + return; + } - if (offset > 0) { - /* first count number of real quoting characters; - * read: non-spaces - * this maybe just plain wrong, but leaving spaces - * within quoting characters is what I consider - * more plain wrong... - */ - for (i = 0; i < offset; i++) - if (line[i] != ' ') - count++; - /* just make sure we're inside quote althoug we - * likely won't have more than SHORT_STRING quote levels... */ - i = (count > SHORT_STRING-1) ? SHORT_STRING-1 : count; - memset (quote, '>', i); - quote[i] = '\0'; + while (fgets (buf, sizeof (buf), in)) { + if (ascii_strncmp ("From ", buf, 4) == 0 || buf[0] == ' ') { + fputc (' ', out); +#if DEBUG + lc++; + len = m_strlen(buf); + if (len > 0) { + c = buf[len-1]; + buf[len-1] = '\0'; + } + debug_print (4, ("f=f: line %d needs space-stuffing: '%s'\n", + lc, buf)); + if (len > 0) + buf[len-1] = c; +#endif + } + fputs (buf, out); } - debug_print (4, ("f=f: quotelevel = %d, new prefix = '%s'\n", - i, NONULL (quote))); - /* if we changed prefix, make sure we respect $stuff_quoted */ - snprintf (dst, dstlen, "%s%s%s%s", NONULL (s->prefix), NONULL (quote), - option (OPTSTUFFQUOTED) && line[offset] != ' ' ? " " : "", - &line[offset]); + fclose (in); + fclose (out); + mutt_set_mtime (hdr->content->filename, tmpfile); + unlink (hdr->content->filename); + m_strreplace(&hdr->content->filename, tmpfile); }