X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=muttlib.c;h=1c8a288ab642fba38e2271c6274c90ed4a363f2c;hp=6ac6dbaef2d21f53c8c359d01b561d1ab172a565;hb=8476307969a605bea67f6b702b0c1e7a52038bed;hpb=529d980f183269a45ba925b4f9ee688b01ad3b22 diff --git a/muttlib.c b/muttlib.c index 6ac6dba..1c8a288 100644 --- a/muttlib.c +++ b/muttlib.c @@ -8,46 +8,25 @@ * please see the file GPL in the top level source directory. */ -#if HAVE_CONFIG_H -# include "config.h" -#endif +#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - #include - #include #include +#include +#include #include "alias.h" #include "mutt.h" -#include "mx.h" #include "attach.h" #include "version.h" #include -#include #include @@ -168,29 +147,6 @@ int mutt_matches_ignore (const char *s, string_list_t * t) return 0; } -/* prepend the path part of *path to *lnk */ -void mutt_expand_link (char *newpath, const char *path, const char *lnk) -{ - const char *lb = NULL; - ssize_t len; - - /* lnk is full path */ - if (*lnk == '/') { - m_strcpy(newpath, _POSIX_PATH_MAX, lnk); - return; - } - - if ((lb = strrchr (path, '/')) == NULL) { - /* no path in lnk */ - m_strcpy(newpath, _POSIX_PATH_MAX, lnk); - return; - } - - len = lb - path + 1; - memcpy (newpath, path, len); - m_strcpy(newpath + len, _POSIX_PATH_MAX - len, lnk); -} - char *mutt_expand_path (char *s, ssize_t slen) { return _mutt_expand_path (s, slen, 0); @@ -343,51 +299,7 @@ char *_mutt_expand_path (char *s, ssize_t slen, int rx) return (s); } -/* move all the headers from extra not present in base into base */ -void mutt_merge_envelopes(ENVELOPE* base, ENVELOPE** extra) -{ - /* copies each existing element if necessary, and sets the element - * to NULL in the source so that envelope_delete doesn't leave us - * with dangling pointers. */ -#define MOVE_ELEM(h) if (!base->h) { base->h = (*extra)->h; (*extra)->h = NULL; } - MOVE_ELEM(return_path); - MOVE_ELEM(from); - MOVE_ELEM(to); - MOVE_ELEM(cc); - MOVE_ELEM(bcc); - MOVE_ELEM(sender); - MOVE_ELEM(reply_to); - MOVE_ELEM(mail_followup_to); - MOVE_ELEM(list_post); - MOVE_ELEM(message_id); - MOVE_ELEM(supersedes); - MOVE_ELEM(date); - MOVE_ELEM(x_label); - if (!base->refs_changed) { - MOVE_ELEM(references); - } - if (!base->irt_changed) { - MOVE_ELEM(in_reply_to); - } - /* real_subj is subordinate to subject */ - if (!base->subject) { - base->subject = (*extra)->subject; - base->real_subj = (*extra)->real_subj; - (*extra)->subject = NULL; - (*extra)->real_subj = NULL; - } - /* spam and user headers should never be hashed, and the new envelope may - * have better values. Use new versions regardless. */ - mutt_buffer_free (&base->spam); - string_list_wipe(&base->userhdrs); - MOVE_ELEM(spam); - MOVE_ELEM(userhdrs); -#undef MOVE_ELEM - - envelope_delete(extra); -} - -void _mutt_mktemp (char *s, const char *src, int line) +void mutt_mktemp (char *s) { snprintf (s, _POSIX_PATH_MAX, "%s/madmutt-%s-%d-%d-%d-%x%x", NONULL (Tempdir), @@ -600,7 +512,7 @@ void mutt_safe_path(char *s, ssize_t l, address_t *a) mutt_save_path(s, l, a); while (*s) { - if (*s == '/' || ISSPACE(*s) || !IsPrint((unsigned char)*s)) + if (*s == '/' || ISSPACE(*s) || !isprint((unsigned char)*s)) *s = '_'; s++; } @@ -815,39 +727,12 @@ void mutt_FormatString (char *dest, /* output buffer */ /* Make sure that the string is printable by changing all non-printable chars to dots, or spaces for non-printable whitespace */ for (cp = dest; *cp; cp++) - if (!IsPrint (*cp) && !((flags & M_FORMAT_TREE) && (*cp <= M_TREE_MAX))) + if (!isprint(*cp) && !((flags & M_FORMAT_TREE) && (*cp <= M_TREE_MAX))) *cp = isspace ((unsigned char) *cp) ? ' ' : '.'; } #endif } -/* This function allows the user to specify a command to read stdout from in - place of a normal file. If the last character in the string is a pipe (|), - then we assume it is a commmand to run instead of a normal file. */ -FILE *mutt_open_read (const char *path, pid_t * thepid) -{ - int len = m_strlen(path); - FILE *f; - - if (path[len - 1] == '|') { - char *s = m_strdup(path); - - /* read from a pipe */ - - s[len - 1] = 0; - mutt_endwin (NULL); - *thepid = mutt_create_filter (s, NULL, &f, NULL); - p_delete(&s); - } else { - f = fopen (path, "r"); - if (!f) - return NULL; - *thepid = -1; - } - - return (f); -} - /* returns 0 if OK to proceed, -1 to abort, 1 to retry */ int mutt_save_confirm (const char *s, struct stat *st) { @@ -944,18 +829,6 @@ time_t mutt_decrease_mtime (const char *f, struct stat *st) return mtime; } -/* sets mtime of 'to' to mtime of 'from' */ -void mutt_set_mtime (const char* from, const char* to) { - struct utimbuf utim; - struct stat st; - - if (stat (from, &st) != -1) { - utim.actime = st.st_mtime; - utim.modtime = st.st_mtime; - utime (to, &utim); - } -} - const char *mutt_make_version (int full) { static char vstring[STRING]; @@ -1028,32 +901,8 @@ int mutt_match_spam_list (const char *s, SPAM_LIST * l, char *text, int x) return 0; } -int mutt_cmp_header (const HEADER * h1, const HEADER * h2) { - if (h1 && h2) { - if (h1->received != h2->received || - h1->date_sent != h2->date_sent || - h1->content->length != h2->content->length || - h1->lines != h2->lines || - h1->zhours != h2->zhours || - h1->zminutes != h2->zminutes || - h1->zoccident != h2->zoccident || - h1->mime != h2->mime || - !mutt_cmp_env (h1->env, h2->env) || - !mutt_cmp_body (h1->content, h2->content)) - return (0); - else - return (1); - } - else { - if (h1 == NULL && h2 == NULL) - return (1); - else - return (0); - } -} - /* return 1 if address lists are strictly identical */ -int mutt_cmp_addr (const address_t * a, const address_t * b) +static int mutt_cmp_addr (const address_t * a, const address_t * b) { while (a && b) { if (m_strcmp(a->mailbox, b->mailbox) || @@ -1069,7 +918,7 @@ int mutt_cmp_addr (const address_t * a, const address_t * b) return (1); } -int mutt_cmp_list (const string_list_t * a, const string_list_t * b) +static int mutt_cmp_list (const string_list_t * a, const string_list_t * b) { while (a && b) { if (m_strcmp(a->data, b->data)) @@ -1084,7 +933,7 @@ int mutt_cmp_list (const string_list_t * a, const string_list_t * b) return (1); } -int mutt_cmp_env (const ENVELOPE * e1, const ENVELOPE * e2) +static int mutt_cmp_env (const ENVELOPE * e1, const ENVELOPE * e2) { if (e1 && e2) { if (m_strcmp(e1->message_id, e2->message_id) || @@ -1108,7 +957,7 @@ int mutt_cmp_env (const ENVELOPE * e1, const ENVELOPE * e2) } } -int mutt_cmp_body (const BODY * b1, const BODY * b2) +static int mutt_cmp_body (const BODY * b1, const BODY * b2) { if (b1->type != b2->type || b1->encoding != b2->encoding || @@ -1119,3 +968,208 @@ int mutt_cmp_body (const BODY * b1, const BODY * b2) return (0); return (1); } +int mutt_cmp_header (const HEADER * h1, const HEADER * h2) { + if (h1 && h2) { + if (h1->received != h2->received || + h1->date_sent != h2->date_sent || + h1->content->length != h2->content->length || + h1->lines != h2->lines || + h1->zhours != h2->zhours || + h1->zminutes != h2->zminutes || + h1->zoccident != h2->zoccident || + h1->mime != h2->mime || + !mutt_cmp_env (h1->env, h2->env) || + !mutt_cmp_body (h1->content, h2->content)) + return (0); + else + return (1); + } + else { + if (h1 == NULL && h2 == NULL) + return (1); + else + return (0); + } +} + + +int mutt_extract_token(BUFFER *dest, BUFFER *tok, int flags) +{ + char ch; + char qc = 0; /* quote char */ + char *pc; + + /* reset the destination pointer to the beginning of the buffer */ + dest->dptr = dest->data; + + tok->dptr = vskipspaces(tok->dptr); + while ((ch = *tok->dptr)) { + if (!qc) { + if ((ISSPACE(ch) && !(flags & M_TOKEN_SPACE)) + || (ch == '#' && !(flags & M_TOKEN_COMMENT)) + || (ch == '=' && (flags & M_TOKEN_EQUAL)) + || (ch == ';' && !(flags & M_TOKEN_SEMICOLON)) + || ((flags & M_TOKEN_PATTERN) && strchr("~=!|", ch))) + { + break; + } + } + + tok->dptr++; + + if (ch == qc) { + qc = 0; /* end of quote */ + } else + if (!qc && (ch == '\'' || ch == '"') && !(flags & M_TOKEN_QUOTE)) { + qc = ch; + } else + if (ch == '\\' && qc != '\'') { + if (!*tok->dptr) + return -1; /* premature end of token */ + + switch (ch = *tok->dptr++) { + case 'c': + case 'C': + if (!*tok->dptr) + return -1; /* premature end of token */ + mutt_buffer_addch(dest, + (ascii_toupper(*tok->dptr) - 'A' + 1) & 0x7f); + tok->dptr++; + break; + case 'r': + mutt_buffer_addch(dest, '\r'); + break; + case 'n': + mutt_buffer_addch(dest, '\n'); + break; + case 't': + mutt_buffer_addch(dest, '\t'); + break; + case 'f': + mutt_buffer_addch(dest, '\f'); + break; + case 'e': + mutt_buffer_addch(dest, '\033'); + break; + default: + if (isdigit((unsigned char)ch) + && isdigit((unsigned char)*tok->dptr) + && isdigit((unsigned char)*(tok->dptr + 1))) + { + mutt_buffer_addch(dest, (ch << 6) + (*tok->dptr << 3) + + *(tok->dptr + 1) - 3504); + tok->dptr += 2; + } else { + mutt_buffer_addch(dest, ch); + } + } + } else + if (ch == '^' && (flags & M_TOKEN_CONDENSE)) { + if (!*tok->dptr) + return -1; /* premature end of token */ + ch = *tok->dptr++; + if (ch == '^') { + mutt_buffer_addch(dest, ch); + } else + if (ch == '[') { + mutt_buffer_addch(dest, '\033'); + } else + if (isalpha((unsigned char)ch)) { + mutt_buffer_addch(dest, ascii_toupper(ch) - 'A' + 1); + } else { + mutt_buffer_addch(dest, '^'); + mutt_buffer_addch(dest, ch); + } + } else + if (ch == '`' && (!qc || qc == '"')) { + FILE *fp; + pid_t pid; + char *cmd, *ptr; + ssize_t expnlen; + BUFFER expn; + int line = 0; + + pc = tok->dptr; + do { + if ((pc = strpbrk(pc, "\\`"))) { + /* skip any quoted chars */ + if (*pc == '\\') + pc += 2; + } + } while (pc && *pc != '`'); + if (!pc) { + return (-1); + } + + cmd = p_dupstr(tok->dptr, pc - tok->dptr); + if ((pid = mutt_create_filter(cmd, NULL, &fp, NULL)) < 0) { + p_delete(&cmd); + return -1; + } + p_delete(&cmd); + + tok->dptr = pc + 1; + + /* read line */ + p_clear(&expn, 1); + expn.data = mutt_read_line(NULL, &expn.dsize, fp, &line); + fclose(fp); + mutt_wait_filter(pid); + + /* if we got output, make a new string consiting of the shell ouptput + plus whatever else was left on the original line */ + /* BUT: If this is inside a quoted string, directly add output to + * the token */ + if (expn.data && qc) { + mutt_buffer_addstr(dest, expn.data); + p_delete(&expn.data); + } else + if (expn.data) { + expnlen = m_strlen(expn.data); + tok->dsize = expnlen + m_strlen(tok->dptr) + 1; + ptr = xmalloc(tok->dsize); + memcpy(ptr, expn.data, expnlen); + strcpy(ptr + expnlen, tok->dptr); /* __STRCPY_CHECKED__ */ + if (tok->destroy) + p_delete(&tok->data); + tok->data = ptr; + tok->dptr = ptr; + tok->destroy = 1; /* mark that the caller should destroy this data */ + ptr = NULL; + p_delete(&expn.data); + } + } else + if (ch == '$' && (!qc || qc == '"') + && (*tok->dptr == '{' || isalpha((unsigned char)*tok->dptr))) + { + char *env = NULL, *var = NULL; + + if (*tok->dptr == '{') { + tok->dptr++; + if ((pc = strchr (tok->dptr, '}'))) { + var = p_dupstr(tok->dptr, pc - tok->dptr); + tok->dptr = pc + 1; + } + } else { + for (pc = tok->dptr; isalnum((unsigned char)*pc) || *pc == '_'; + pc++); + var = p_dupstr(tok->dptr, pc - tok->dptr); + tok->dptr = pc; + } + if (var) { + char tmp[STRING]; + if ((env = getenv (var)) + || (mutt_option_value (var, tmp, sizeof (tmp)) && (env = tmp))) + { + mutt_buffer_addstr (dest, env); + } + } + p_delete(&var); + } else { + mutt_buffer_addch(dest, ch); + } + } + mutt_buffer_addch(dest, 0); /* terminate the string */ + tok->dptr = vskipspaces(tok->dptr); + return 0; +}