#endif
#include "mutt.h"
+#include "ascii.h"
+#include "buffer.h"
+#include "enter.h"
#include "mutt_curses.h"
#include "mime.h"
-#include "mailbox.h"
#include "mx.h"
#include "url.h"
+#include "attach.h"
#include "reldate.h"
+#include "version.h"
#ifdef USE_IMAP
#include "imap.h"
+#include "imap/mx_imap.h"
#endif
#include "mutt_crypt.h"
#include "lib/mem.h"
#include "lib/intl.h"
#include "lib/str.h"
+#include "lib/debug.h"
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <utime.h>
+#define SW (option(OPTMBOXPANE)?SidebarWidth:0)
+
BODY *mutt_new_body (void)
{
- BODY *p = (BODY *) safe_calloc (1, sizeof (BODY));
+ BODY *p = (BODY *) mem_calloc (1, sizeof (BODY));
p->disposition = DISPATTACH;
p->use_disp = 1;
* Renamed to mutt_adv_mktemp so I only have to change where it's
* called, and not all possible cases.
*/
-void mutt_adv_mktemp (char *s, size_t l)
+void mutt_adv_mktemp (const char* dir, char *s, size_t l)
{
char buf[_POSIX_PATH_MAX];
char tmp[_POSIX_PATH_MAX];
size_t sl;
struct stat sb;
- strfcpy (buf, NONULL (Tempdir), sizeof (buf));
+ strfcpy (buf, dir && *dir ? dir : NONULL (Tempdir), sizeof (buf));
mutt_expand_path (buf, sizeof (buf));
if (s[0] == '\0') {
snprintf (s, l, "%s/muttXXXXXX", buf);
mktemp (s);
if (period != NULL) {
*period = '.';
- sl = mutt_strlen (s);
+ sl = str_len (s);
strfcpy (s + sl, period, l - sl);
}
}
tmp[0] = '\0';
}
- mutt_adv_mktemp (tmp, sizeof (tmp));
+ mutt_adv_mktemp (NULL, tmp, sizeof (tmp));
if (mutt_save_attachment (fp, src, tmp, 0, NULL) == -1)
return -1;
b->parts = NULL;
b->next = NULL;
- b->filename = safe_strdup (tmp);
+ b->filename = str_dup (tmp);
b->use_disp = use_disp;
b->unlink = 1;
if (mutt_is_text_part (b))
b->noconv = 1;
- b->xtype = safe_strdup (b->xtype);
- b->subtype = safe_strdup (b->subtype);
- b->form_name = safe_strdup (b->form_name);
- b->filename = safe_strdup (b->filename);
- b->d_filename = safe_strdup (b->d_filename);
- b->description = safe_strdup (b->description);
+ b->xtype = str_dup (b->xtype);
+ b->subtype = str_dup (b->subtype);
+ b->form_name = str_dup (b->form_name);
+ b->filename = str_dup (b->filename);
+ b->d_filename = str_dup (b->d_filename);
+ b->description = str_dup (b->description);
/*
* we don't seem to need the HEADER structure currently.
for (par = b->parameter, ppar = &b->parameter; par;
ppar = &(*ppar)->next, par = par->next) {
*ppar = mutt_new_parameter ();
- (*ppar)->attribute = safe_strdup (par->attribute);
- (*ppar)->value = safe_strdup (par->value);
+ (*ppar)->attribute = str_dup (par->attribute);
+ (*ppar)->value = str_dup (par->value);
}
mutt_stamp_attachment (b);
if (b->parameter)
mutt_free_parameter (&b->parameter);
if (b->unlink && b->filename) {
- dprint (1, (debugfile, "mutt_free_body: Unlinking %s.\n", b->filename));
+ debug_print (1, ("unlinking %s.\n", b->filename));
unlink (b->filename);
}
else if (b->filename)
- dprint (1,
- (debugfile, "mutt_free_body: Not unlinking %s.\n",
- b->filename));
+ debug_print (1, ("not unlinking %s.\n", b->filename));
- FREE (&b->filename);
- FREE (&b->content);
- FREE (&b->xtype);
- FREE (&b->subtype);
- FREE (&b->description);
- FREE (&b->form_name);
+ mem_free (&b->filename);
+ mem_free (&b->content);
+ mem_free (&b->xtype);
+ mem_free (&b->subtype);
+ mem_free (&b->description);
+ mem_free (&b->form_name);
if (b->hdr) {
/* Don't free twice (b->hdr->content = b->parts) */
if (b->parts)
mutt_free_body (&b->parts);
- FREE (&b);
+ mem_free (&b);
}
*p = 0;
PARAMETER *o;
while (t) {
- FREE (&t->attribute);
- FREE (&t->value);
+ mem_free (&t->attribute);
+ mem_free (&t->value);
o = t;
t = t->next;
- FREE (&o);
+ mem_free (&o);
}
*p = 0;
}
-LIST *mutt_add_list (LIST * head, const char *data)
-{
- LIST *tmp;
-
- for (tmp = head; tmp && tmp->next; tmp = tmp->next);
- if (tmp) {
- tmp->next = safe_malloc (sizeof (LIST));
- tmp = tmp->next;
- }
- else
- head = tmp = safe_malloc (sizeof (LIST));
-
- tmp->data = safe_strdup (data);
- tmp->next = NULL;
- return head;
-}
-
-void mutt_free_list (LIST ** list)
-{
- LIST *p;
-
- if (!list)
- return;
- while (*list) {
- p = *list;
- *list = (*list)->next;
- FREE (&p->data);
- FREE (&p);
- }
-}
-
HEADER *mutt_dup_header (HEADER * h)
{
HEADER *hnew;
return;
mutt_free_envelope (&(*h)->env);
mutt_free_body (&(*h)->content);
- FREE (&(*h)->maildir_flags);
- FREE (&(*h)->tree);
- FREE (&(*h)->path);
+ mem_free (&(*h)->maildir_flags);
+ mem_free (&(*h)->tree);
+ mem_free (&(*h)->path);
#ifdef MIXMASTER
mutt_free_list (&(*h)->chain);
#endif
#if defined USE_POP || defined USE_IMAP || defined USE_NNTP
- FREE (&(*h)->data);
+ mem_free (&(*h)->data);
#endif
- FREE (h);
+ mem_free (h);
}
/* returns true if the header contained in "s" is in list "t" */
int mutt_matches_ignore (const char *s, LIST * t)
{
for (; t; t = t->next) {
- if (!ascii_strncasecmp (s, t->data, mutt_strlen (t->data))
+ if (!ascii_strncasecmp (s, t->data, str_len (t->data))
|| *t->data == '*')
return 1;
}
return 0;
}
-/* prepend the path part of *path to *link */
-void mutt_expand_link (char *newpath, const char *path, const char *link)
+/* prepend the path part of *path to *lnk */
+void mutt_expand_link (char *newpath, const char *path, const char *lnk)
{
const char *lb = NULL;
size_t len;
- /* link is full path */
- if (*link == '/') {
- strfcpy (newpath, link, _POSIX_PATH_MAX);
+ /* lnk is full path */
+ if (*lnk == '/') {
+ strfcpy (newpath, lnk, _POSIX_PATH_MAX);
return;
}
if ((lb = strrchr (path, '/')) == NULL) {
- /* no path in link */
- strfcpy (newpath, link, _POSIX_PATH_MAX);
+ /* no path in lnk */
+ strfcpy (newpath, lnk, _POSIX_PATH_MAX);
return;
}
len = lb - path + 1;
memcpy (newpath, path, len);
- strfcpy (newpath + len, link, _POSIX_PATH_MAX - len);
+ strfcpy (newpath + len, lnk, _POSIX_PATH_MAX - len);
}
char *mutt_expand_path (char *s, size_t slen)
char tmp[_POSIX_PATH_MAX];
char *t;
- char *tail = "";
+ const char *tail = "";
int recurse = 0;
case '+':
{
#ifdef USE_IMAP
- /* if folder = {host} or imap[s]://host/: don't append slash */
- if (mx_is_imap (NONULL (Maildir)) &&
- (Maildir[mutt_strlen (Maildir) - 1] == '}' ||
- Maildir[mutt_strlen (Maildir) - 1] == '/'))
+ /* if folder = imap[s]://host/: don't append slash */
+ if (imap_is_magic (NONULL (Maildir), NULL) == M_IMAP &&
+ Maildir[str_len (Maildir) - 1] == '/')
strfcpy (p, NONULL (Maildir), sizeof (p));
else
#endif
}
while (recurse);
-#ifdef USE_IMAP
- /* Rewrite IMAP path in canonical form - aids in string comparisons of
- * folders. May possibly fail, in which case s should be the same. */
- if (mx_is_imap (s))
- imap_expand_path (s, slen);
-#endif
-
return (s);
}
else
strfcpy (dest, pw->pw_gecos, destlen);
- pwnl = mutt_strlen (pw->pw_name);
+ pwnl = str_len (pw->pw_name);
for (idx = 0; dest[idx]; idx++) {
if (dest[idx] == '&') {
for (q = *p; q; q = q->next) {
if (ascii_strcasecmp (attribute, q->attribute) == 0) {
- mutt_str_replace (&q->value, value);
+ str_replace (&q->value, value);
return;
}
}
q = mutt_new_parameter ();
- q->attribute = safe_strdup (attribute);
- q->value = safe_strdup (value);
+ q->attribute = str_dup (attribute);
+ q->value = str_dup (value);
q->next = *p;
*p = q;
}
rfc822_free_address (&(*p)->reply_to);
rfc822_free_address (&(*p)->mail_followup_to);
- FREE (&(*p)->list_post);
- FREE (&(*p)->subject);
+ mem_free (&(*p)->list_post);
+ mem_free (&(*p)->subject);
/* real_subj is just an offset to subject and shouldn't be freed */
- FREE (&(*p)->message_id);
- FREE (&(*p)->supersedes);
- FREE (&(*p)->date);
- FREE (&(*p)->x_label);
- FREE (&(*p)->organization);
+ mem_free (&(*p)->message_id);
+ mem_free (&(*p)->supersedes);
+ mem_free (&(*p)->date);
+ mem_free (&(*p)->x_label);
+ mem_free (&(*p)->organization);
#ifdef USE_NNTP
- FREE (&(*p)->newsgroups);
- FREE (&(*p)->xref);
- FREE (&(*p)->followup_to);
- FREE (&(*p)->x_comment_to);
+ mem_free (&(*p)->newsgroups);
+ mem_free (&(*p)->xref);
+ mem_free (&(*p)->followup_to);
+ mem_free (&(*p)->x_comment_to);
#endif
mutt_buffer_free (&(*p)->spam);
mutt_free_list (&(*p)->references);
mutt_free_list (&(*p)->in_reply_to);
mutt_free_list (&(*p)->userhdrs);
- FREE (p);
+ mem_free (p);
+}
+
+/* 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 mutt_free_envelope 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);
+ mutt_free_list (&base->userhdrs);
+ MOVE_ELEM(spam);
+ MOVE_ELEM(userhdrs);
+#undef MOVE_ELEM
+
+ mutt_free_envelope(extra);
}
void _mutt_mktemp (char *s, const char *src, int line)
{
- snprintf (s, _POSIX_PATH_MAX, "%s/mutt-%s-%d-%d-%d", NONULL (Tempdir),
- NONULL (Hostname), (int) getuid (), (int) getpid (), Counter++);
- dprint (1,
- (debugfile, "%s:%d: mutt_mktemp returns \"%s\".\n", src, line, s));
+
+ snprintf (s, _POSIX_PATH_MAX, "%s/muttng-%s-%d-%d-%d-%x%x", NONULL (Tempdir),
+ NONULL (Hostname), (int) getuid (), (int) getpid (), Counter++,
+ (unsigned int) rand(), (unsigned int) rand());
+ debug_print (1, ("%s:%d: mutt_mktemp returns \"%s\".\n", src, line, s));
unlink (s);
}
while (*p) {
t = *p;
*p = (*p)->next;
- FREE (&t->name);
+ mem_free (&t->name);
rfc822_free_address (&t->addr);
- FREE (&t);
+ mem_free (&t);
}
}
}
*q = 0;
- if (mutt_strncmp (s, Maildir, (len = mutt_strlen (Maildir))) == 0 &&
+ if (str_ncmp (s, Maildir, (len = str_len (Maildir))) == 0 &&
s[len] == '/') {
*s++ = '=';
- memmove (s, s + len, mutt_strlen (s + len) + 1);
+ memmove (s, s + len, str_len (s + len) + 1);
}
- else if (mutt_strncmp (s, Homedir, (len = mutt_strlen (Homedir))) == 0 &&
+ else if (str_ncmp (s, Homedir, (len = str_len (Homedir))) == 0 &&
s[len] == '/') {
*s++ = '~';
- memmove (s, s + len - 1, mutt_strlen (s + len - 1) + 1);
+ memmove (s, s + len - 1, str_len (s + len - 1) + 1);
}
}
size_t slen;
int found = 0;
- slen = mutt_strlen (src);
+ slen = str_len (src);
destlen--;
for (p = fmt, d = dest; destlen && *p; p++) {
*d = '\0';
if (!found && destlen > 0) {
- safe_strcat (dest, destlen, " ");
- safe_strcat (dest, destlen, src);
+ str_cat (dest, destlen, " ");
+ str_cat (dest, destlen, src);
}
}
(_("File is a directory, save under it? [(y)es, (n)o, (a)ll]"),
_("yna"))) {
case 3: /* all */
- mutt_str_replace (directory, fname);
+ str_replace (directory, fname);
break;
case 1: /* yes */
- FREE (directory);
+ mem_free (directory);
break;
case -1: /* abort */
- FREE (directory);
+ mem_free (directory);
return -1;
case 2: /* no */
- FREE (directory);
+ mem_free (directory);
return 1;
}
}
if ((p = strpbrk (d, "%@")))
*p = 0;
}
- mutt_strlower (d);
+ str_tolower (d);
}
else
*d = 0;
ret++;
s++;
}
- return (mutt_strlen (p));
+ return (str_len (p));
}
void mutt_FormatString (char *dest, /* output buffer */
if (DrawFullLine || option (OPTSTATUSONTOP))
count = (COLS < destlen ? COLS : destlen);
else
- count =
- ((COLS - SidebarWidth) <
- destlen ? (COLS - SidebarWidth) : destlen);
+ count = ((COLS - SW) < destlen ? (COLS - SW) : destlen);
if (count > col) {
count -= col; /* how many columns left on this line */
mutt_FormatString (buf, sizeof (buf), src, callback, data, flags);
- wid = mutt_strlen (buf);
+ wid = str_len (buf);
if (count > wid) {
count -= wid; /* how many chars to pad */
memset (wptr, ch, count);
break; /* skip rest of input */
}
else {
- short tolower = 0;
+ short lower = 0;
short nodots = 0;
while (ch == '_' || ch == ':') {
if (ch == '_')
- tolower = 1;
+ lower = 1;
else if (ch == ':')
nodots = 1;
callback (buf, sizeof (buf), ch, src, prefix, ifstring, elsestring,
data, flags);
- if (tolower)
- mutt_strlower (buf);
+ if (lower)
+ str_tolower (buf);
if (nodots) {
char *p = buf;
*p = '_';
}
- if ((len = mutt_strlen (buf)) + wlen > destlen)
+ if ((len = str_len (buf)) + wlen > destlen)
len = (destlen - wlen > 0) ? (destlen - wlen) : 0;
memcpy (wptr, buf, len);
}
else {
unsigned int bar = mutt_skipchars (src, "%\\");
- char *bar2 = safe_malloc (bar + 1);
+ char *bar2 = mem_malloc (bar + 1);
strfcpy (bar2, src, bar + 1);
while (bar--) {
wlen++;
}
col += mutt_strwidth (bar2);
- FREE (&bar2);
+ mem_free (&bar2);
}
}
*wptr = 0;
then we assume it is a commmand to run instead of a normal file. */
FILE *mutt_open_read (const char *path, pid_t * thepid)
{
- FILE *f;
- struct stat s;
-
- int len = mutt_strlen (path);
-
- if (path[len - 1] == '|') {
- /* read from a pipe */
-
- char *s = safe_strdup (path);
-
- s[len - 1] = 0;
- mutt_endwin (NULL);
- *thepid = mutt_create_filter (s, NULL, &f, NULL);
- FREE (&s);
- }
- else {
- if (stat (path, &s) < 0)
- return (NULL);
- if (S_ISDIR (s.st_mode)) {
- errno = EINVAL;
- return (NULL);
+ int len = str_len (path);
+ FILE *f;
+
+ if (path[len - 1] == '|') {
+ char *s = str_dup (path);
+
+ /* read from a pipe */
+
+ s[len - 1] = 0;
+ mutt_endwin (NULL);
+ *thepid = mutt_create_filter (s, NULL, &f, NULL);
+ mem_free (&s);
+ } else {
+ struct stat st;
+
+ if (stat (path, &st) < 0)
+ return (NULL);
+ if (S_ISDIR (st.st_mode)) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ f = fopen (path, "r");
+ *thepid = -1;
}
- f = fopen (path, "r");
- *thepid = -1;
- }
- return (f);
+
+ return (f);
}
/* returns 0 if OK to proceed, -1 to abort, 1 to retry */
}
#endif
- if (stat (s, st) != -1) {
- if (magic == -1) {
- mutt_error (_("%s is not a mailbox!"), s);
- return 1;
- }
-
+ if (magic > 0 && !mx_access (s, W_OK)) {
if (option (OPTCONFIRMAPPEND) &&
- (!TrashPath || (mutt_strcmp (s, TrashPath) != 0)))
+ (!TrashPath || (str_cmp (s, TrashPath) != 0))) {
/* if we're appending to the trash, there's no point in asking */
- {
snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
ret = 1;
ret = -1;
}
}
+
+ if (stat (s, st) != -1) {
+ if (magic == -1) {
+ mutt_error (_("%s is not a mailbox!"), s);
+ return 1;
+ }
+ }
else {
#ifdef USE_IMAP
if (magic != M_IMAP)
return (ret);
}
-void state_prefix_putc (char c, STATE * s)
-{
- if (s->flags & M_PENDINGPREFIX) {
- int i;
-
- i = mutt_strlen (Quotebuf);
- Quotebuf[i++] = c;
- Quotebuf[i] = '\0';
- if (i == sizeof (Quotebuf) - 1 || c == '\n') {
- char buf[2 * SHORT_STRING];
- int j = 0, offset = 0;
- regmatch_t pmatch[1];
-
- state_reset_prefix (s);
- while (regexec
- ((regex_t *) QuoteRegexp.rx, &Quotebuf[offset], 1, pmatch,
- 0) == 0)
- offset += pmatch->rm_eo;
-
- if (!option (OPTQUOTEEMPTY) && Quotebuf[offset] == '\n') {
- buf[0] = '\n';
- buf[1] = '\0';
- }
- else if (option (OPTQUOTEQUOTED) && offset) {
- for (i = 0; i < offset; i++)
- if (Quotebuf[i] != ' ')
- j = i;
- strncpy (buf, Quotebuf, j + 1);
- strcpy (buf + j + 1, Quotebuf + j);
- }
- else
- snprintf (buf, sizeof (buf), "%s%s", NONULL (s->prefix), Quotebuf);
-
- state_puts (buf, s);
- }
- }
- else
- state_putc (c, s);
-
- if (c == '\n') {
- state_set_prefix (s);
- Quotebuf[0] = '\0';
- }
-}
-
-int state_printf (STATE * s, const char *fmt, ...)
-{
- int rv;
- va_list ap;
-
- va_start (ap, fmt);
- rv = vfprintf (s->fpout, fmt, ap);
- va_end (ap);
-
- return rv;
-}
-
-void state_mark_attach (STATE * s)
-{
- if ((s->flags & M_DISPLAY) && !mutt_strcmp (Pager, "builtin"))
- state_puts (AttachmentMarker, s);
-}
-
-void state_attach_puts (const char *t, STATE * s)
-{
- if (*t != '\n')
- state_mark_attach (s);
- while (*t) {
- state_putc (*t, s);
- if (*t++ == '\n' && *t)
- if (*t != '\n')
- state_mark_attach (s);
- }
-}
-
void mutt_display_sanitize (char *s)
{
for (; *s; s++) {
sleep (s);
}
-/*
- * Creates and initializes a BUFFER*. If passed an existing BUFFER*,
- * just initializes. Frees anything already in the buffer.
- *
- * Disregards the 'destroy' flag, which seems reserved for caller.
- * This is bad, but there's no apparent protocol for it.
- */
-BUFFER *mutt_buffer_init (BUFFER * b)
-{
- if (!b) {
- b = safe_malloc (sizeof (BUFFER));
- if (!b)
- return NULL;
- }
- else {
- FREE(&b->data);
- }
- memset (b, 0, sizeof (BUFFER));
- return b;
-}
-
-/*
- * Creates and initializes a BUFFER*. If passed an existing BUFFER*,
- * just initializes. Frees anything already in the buffer. Copies in
- * the seed string.
- *
- * Disregards the 'destroy' flag, which seems reserved for caller.
- * This is bad, but there's no apparent protocol for it.
- */
-BUFFER *mutt_buffer_from (BUFFER * b, char *seed)
-{
- if (!seed)
- return NULL;
-
- b = mutt_buffer_init (b);
- b->data = safe_strdup (seed);
- b->dsize = mutt_strlen (seed);
- b->dptr = (char *) b->data + b->dsize;
- return b;
-}
-
-void mutt_buffer_addstr (BUFFER * buf, const char *s)
-{
- mutt_buffer_add (buf, s, mutt_strlen (s));
-}
-
-void mutt_buffer_addch (BUFFER * buf, char c)
-{
- mutt_buffer_add (buf, &c, 1);
-}
-
-void mutt_buffer_free (BUFFER ** p)
-{
- if (!p || !*p)
- return;
-
- FREE (&(*p)->data);
- /* dptr is just an offset to data and shouldn't be freed */
- FREE (p);
-}
-
-/* dynamically grows a BUFFER to accomodate s, in increments of 128 bytes.
- * Always one byte bigger than necessary for the null terminator, and
- * the buffer is always null-terminated */
-void mutt_buffer_add (BUFFER * buf, const char *s, size_t len)
-{
- size_t offset;
-
- if (buf->dptr + len + 1 > buf->data + buf->dsize) {
- offset = buf->dptr - buf->data;
- buf->dsize += len < 128 ? 128 : len + 1;
- safe_realloc ((void **) &buf->data, buf->dsize);
- buf->dptr = buf->data + offset;
- }
- memcpy (buf->dptr, s, len);
- buf->dptr += len;
- *(buf->dptr) = '\0';
-}
-
/* Decrease a file's modification time by 1 second */
-
time_t mutt_decrease_mtime (const char *f, struct stat *st)
{
struct utimbuf utim;
return mtime;
}
-const char *mutt_make_version (void)
+/* 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];
- snprintf (vstring, sizeof (vstring), "Mutt-ng %s (%s)",
- MUTT_VERSION, ReleaseDate);
+ if (full)
+ snprintf (vstring, sizeof (vstring), "Mutt-ng %s-r%s (based "
+ "on Mutt 1.5.11/%s)", MUTT_VERSION, MUTT_REVISION,
+ ReleaseDate);
+ else
+ snprintf (vstring, sizeof (vstring), "mutt-ng/%s-r%s",
+ MUTT_VERSION, MUTT_REVISION);
return vstring;
}
p = *list;
*list = (*list)->next;
rx_free (&p->rx);
- FREE(&p->template);
- FREE(&p);
+ mem_free(&p->template);
+ mem_free(&p);
}
}
for (; l; l = l->next) {
/* If this pattern needs more matches, expand pmatch. */
if (l->nmatch > nmatch) {
- safe_realloc (&pmatch, l->nmatch * sizeof (regmatch_t));
+ mem_realloc (&pmatch, l->nmatch * sizeof (regmatch_t));
nmatch = l->nmatch;
}
if (regexec
(l->rx->rx, s, (size_t) l->nmatch, (regmatch_t *) pmatch,
(int) 0) == 0) {
- dprint (5,
- (debugfile, "mutt_match_spam_list: %s matches %s\n", s,
- l->rx->pattern));
- dprint (5,
- (debugfile, "mutt_match_spam_list: %d subs\n",
- l->rx->rx->re_nsub));
+ debug_print (5, ("%s matches %s\n%d subst", s, l->rx->pattern, l->rx->rx->re_nsub));
/* Copy template into text, with substitutions. */
for (p = l->template; *p;) {
if (*p == '%') {
n = atoi (++p); /* find pmatch index */
- while (isdigit (*p))
+ while (isdigit ((unsigned char) *p))
++p; /* skip subst token */
for (i = pmatch[n].rm_so; (i < pmatch[n].rm_eo) && (tlen < x); i++)
text[tlen++] = s[i];
}
}
text[tlen] = '\0';
- dprint (5, (debugfile, "mutt_match_spam_list: \"%s\"\n", text));
+ debug_print (5, ("\"%s\"\n", text));
return 1;
}
}
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 * a, const ADDRESS * b)
+{
+ while (a && b) {
+ if (str_cmp (a->mailbox, b->mailbox) ||
+ str_cmp (a->personal, b->personal))
+ return (0);
+
+ a = a->next;
+ b = b->next;
+ }
+ if (a || b)
+ return (0);
+
+ return (1);
+}
+
+int mutt_cmp_list (const LIST * a, const LIST * b)
+{
+ while (a && b) {
+ if (str_cmp (a->data, b->data))
+ return (0);
+
+ a = a->next;
+ b = b->next;
+ }
+ if (a || b)
+ return (0);
+
+ return (1);
+}
+
+int mutt_cmp_env (const ENVELOPE * e1, const ENVELOPE * e2)
+{
+ if (e1 && e2) {
+ if (str_cmp (e1->message_id, e2->message_id) ||
+ str_cmp (e1->subject, e2->subject) ||
+ !mutt_cmp_list (e1->references, e2->references) ||
+ !mutt_cmp_addr (e1->from, e2->from) ||
+ !mutt_cmp_addr (e1->sender, e2->sender) ||
+ !mutt_cmp_addr (e1->reply_to, e2->reply_to) ||
+ !mutt_cmp_addr (e1->to, e2->to) ||
+ !mutt_cmp_addr (e1->cc, e2->cc) ||
+ !mutt_cmp_addr (e1->return_path, e2->return_path))
+ return (0);
+ else
+ return (1);
+ }
+ else {
+ if (e1 == NULL && e2 == NULL)
+ return (1);
+ else
+ return (0);
+ }
+}
+
+int mutt_cmp_param (const PARAMETER * p1, const PARAMETER * p2)
+{
+ while (p1 && p2) {
+ if (str_cmp (p1->attribute, p2->attribute) ||
+ str_cmp (p1->value, p2->value))
+ return (0);
+
+ p1 = p1->next;
+ p2 = p2->next;
+ }
+ if (p1 || p2)
+ return (0);
+
+ return (1);
+}
+
+int mutt_cmp_body (const BODY * b1, const BODY * b2)
+{
+ if (b1->type != b2->type ||
+ b1->encoding != b2->encoding ||
+ str_cmp (b1->subtype, b2->subtype) ||
+ str_cmp (b1->description, b2->description) ||
+ !mutt_cmp_param (b1->parameter, b2->parameter) ||
+ b1->length != b2->length)
+ return (0);
+ return (1);
+}