mutt_stamp_attachment (a);
}
else
- mutt_perror (fpin ? tempfile : a->filename);
+ mutt_perror(fpin ? tempfile : a->filename);
if (fpin)
fclose (fpin);
char tempfile[_POSIX_PATH_MAX];
if ((fp = safe_fopen (a->filename, "r")) == NULL) {
- mutt_perror _("Failure to open file to parse headers.");
+ mutt_perror (_("Failure to open file to parse headers."));
goto bailout;
}
fseek (fp, b->offset, 0);
mutt_mktemp (tempfile);
if ((tfp = safe_fopen (tempfile, "w")) == NULL) {
- mutt_perror _("Failure to open file to strip headers.");
+ mutt_perror (_("Failure to open file to strip headers."));
goto bailout;
}
fclose (tfp);
mutt_unlink (a->filename);
if (mutt_rename_file (tempfile, a->filename) != 0) {
- mutt_perror _("Failure to rename file.");
+ mutt_perror (_("Failure to rename file."));
goto bailout;
}
thepid = mutt_create_filter (path, &s.fpout, NULL, NULL);
if (thepid < 0) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
goto bail;
}
thepid = mutt_create_filter (path, &ofp, NULL, NULL);
if (thepid < 0) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
safe_fclose (&ifp);
goto bail;
}
if ((thepid = mutt_create_filter (command, &fpout, NULL, NULL)) < 0) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
rfc1524_free_entry (&entry);
safe_fclose (&ifp);
mutt_endwin (NULL);
if ((thepid =
mutt_create_filter (NONULL (PrintCmd), &fpout, NULL, NULL)) < 0) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
goto bail0;
}
case 'N':
#ifdef USE_IMAP
- if (mx_is_imap (folder->ff->desc)) {
+ if (mx_get_magic (folder->ff->desc) == M_IMAP) {
if (!optional) {
snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
snprintf (dest, destlen, tmp, folder->ff->new);
for (i = 0; i < Incoming->length; i++) {
tmp = (BUFFY*) Incoming->data[i];
#ifdef USE_IMAP
- if (mx_is_imap (tmp->path)) {
+ if (mx_get_magic (tmp->path) == M_IMAP) {
add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
continue;
}
#endif
#ifdef USE_POP
- if (mx_is_pop (tmp->path)) {
+ if (mx_get_magic (tmp->path) == M_POP) {
add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
continue;
}
#endif
#ifdef USE_NNTP
- if (mx_is_nntp (tmp->path)) {
+ if (mx_get_magic (tmp->path) == M_NNTP) {
add_folder (menu, state, tmp->path, NULL, NULL, tmp->new);
continue;
}
if (*f) {
mutt_expand_path (f, flen);
#ifdef USE_IMAP
- if (mx_is_imap (f)) {
+ if (mx_get_magic (f) == M_IMAP) {
init_state (&state, NULL);
state.imap_browse = 1;
imap_browse (f, &state);
strfcpy (LastDir, NONULL (Maildir), sizeof (LastDir));
#ifdef USE_IMAP
- if (!buffy && mx_is_imap (LastDir)) {
+ if (!buffy && mx_get_magic (LastDir) == M_IMAP) {
init_state (&state, NULL);
state.imap_browse = 1;
imap_browse (LastDir, &state);
buffy = 0;
mutt_expand_path (buf, sizeof (buf));
#ifdef USE_IMAP
- if (mx_is_imap (buf)) {
+ if (mx_get_magic (buf) == M_IMAP) {
strfcpy (LastDir, buf, sizeof (LastDir));
destroy_state (&state);
init_state (&state, NULL);
goto bail;
}
#ifdef USE_IMAP
- else if (mx_is_imap (LastDir)) {
+ else if (mx_get_magic (LastDir) == M_IMAP) {
init_state (&state, NULL);
state.imap_browse = 1;
imap_browse (LastDir, &state);
#define _BROWSER_H 1
#ifdef USE_NNTP
-#include "nntp.h"
+#include "nntp/nntp.h"
#endif
struct folder_file {
for (i = 0; i < Incoming->length; i++) {
tmp = (BUFFY*) Incoming->data[i];
#ifdef USE_IMAP
- if (mx_is_imap (tmp->path))
+ if (mx_get_magic (tmp->path) == M_IMAP)
tmp->magic = M_IMAP;
else
#endif
#ifdef USE_POP
- if (mx_is_pop (tmp->path))
+ if (mx_get_magic (tmp->path) == M_IMAP)
tmp->magic = M_POP;
else
#endif
#ifdef USE_NNTP
- if ((tmp->magic == M_NNTP) || mx_is_nntp (tmp->path))
+ if (mx_get_magic (tmp->path) == M_NNTP)
tmp->magic = M_NNTP;
else
#endif
mutt_endwin (NULL);
if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) {
- mutt_perror _("Can't create filter process");
+ mutt_perror (_("Can't create filter process"));
return 1;
}
M_MESSAGEHOOK);
mutt_endwin (NULL);
if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) {
- mutt_perror _("Can't create filter process");
+ mutt_perror (_("Can't create filter process"));
return 1;
}
else {
mutt_endwin (NULL);
if ((thepid = mutt_create_filter (cmd, &fpout, NULL, NULL)) < 0) {
- mutt_perror _("Can't create filter process");
+ mutt_perror (_("Can't create filter process"));
return 1;
}
mutt_message (_("Copying to %s..."), buf);
#ifdef USE_IMAP
- if (Context->magic == M_IMAP && !(decode || decrypt) && mx_is_imap (buf)) {
+ if (Context->magic == M_IMAP && !(decode || decrypt) && mx_get_magic (buf) == M_IMAP) {
switch (imap_copy_messages (Context, h, buf, delete)) {
/* success */
case 0:
if ((ifp = safe_fopen (filename, "a")))
fclose (ifp);
if (_mutt_rename_file (filename, oldfile, 1)) {
- mutt_perror _("Unable to create backup file");
+ mutt_perror (_("Unable to create backup file"));
return (-1);
}
dprint (1, (debugfile, "Opening %s\n", oldfile));
if (!(ifp = safe_fopen (oldfile, "r"))) {
- mutt_perror _("Unable to open backup file for reading");
+ mutt_perror (_("Unable to open backup file for reading"));
return (-1);
}
dprint (1, (debugfile, "Opening %s\n", filename));
if (!(ofp = safe_fopen (filename, "w"))) {
fclose (ifp);
- mutt_perror _("Unable to open new file for writing");
+ mutt_perror (_("Unable to open new file for writing"));
return (-1);
}
else
strfcpy (imap_path, s, sizeof (imap_path));
- if (mx_is_imap (imap_path))
+ if (mx_get_magic (imap_path) == M_IMAP)
return imap_complete (s, slen, imap_path);
#endif
#endif
mutt_expand_path (fname, sizeof (fname));
#ifdef USE_IMAP
- if (!mx_is_imap (fname))
+ if (mx_get_magic (fname) != M_IMAP)
#endif
#ifdef USE_POP
- if (!mx_is_pop (fname))
+ if (mx_get_magic (fname) != M_POP)
#endif
#ifdef USE_NNTP
- if (!mx_is_nntp (fname) && !option (OPTNEWS))
+ if (mx_get_magic (fname) != M_NNTP && !option (OPTNEWS))
#endif
/* check to make sure the file exists and is readable */
if (access (fname, R_OK) == -1) {
#ifdef USE_COMPRESSED
#include "mx.h"
+#include "mbox.h"
#include "mutt_curses.h"
#include "lib/mem.h"
return (0);
}
+mx_t* compress_reg_mx (void) {
+ mx_t* fmt = safe_calloc (1, sizeof (mx_t));
+ fmt->type = M_COMPRESSED;
+ fmt->local = 1;
+ fmt->mx_is_magic = mbox_is_magic;
+ fmt->mx_check_empty = mbox_check_empty;
+ fmt->mx_access = access;
+ fmt->mx_open_mailbox = mutt_open_read_compressed;
+ return (fmt);
+}
+
#endif /* USE_COMPRESSED */
* It's licensed under the GNU General Public License,
* please see the file GPL in the top level source directory.
*/
+#ifndef _COMPRESS_H
+#define _COMPRESS_H
+
+#include "mx.h"
int mutt_can_read_compressed (const char *);
int mutt_can_append_compressed (const char *);
int mutt_test_compress_command (const char *);
int mutt_check_mailbox_compressed (CONTEXT *);
void mutt_fast_close_compressed (CONTEXT *);
+
+mx_t* compress_reg_mx (void);
+
+#endif /* _COMPRESS_H */
}
}
-void mutt_perror (const char *s)
+void _mutt_perror (const char *s, const char* filename, int line)
{
char *p = strerror (errno);
dprint (1, (debugfile, "%s: %s (errno = %d)\n", s,
p ? p : "unknown error", errno));
- mutt_error ("%s: %s (errno = %d)", s, p ? p : _("unknown error"), errno);
+ mutt_error ("%s: %s (errno = %d) from %s:%i", s, p ? p : _("unknown error"), errno, filename, line);
}
int mutt_any_key_to_continue (const char *s)
}
if (thepid < 0) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
if (s->flags & M_DISPLAY) {
state_mark_attach (s);
EXTRA_DIST = BUGS README TODO auth_anon.c auth_cram.c auth_gss.c auth_sasl.c
-INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/intl -I$(top_srcdir)/nntp
+INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/intl
noinst_LIBRARIES = libimap.a
-noinst_HEADERS = auth.h imap_private.h message.h
+noinst_HEADERS = auth.h imap_private.h message.h mx_imap.h
-libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
- message.c utf7.c util.c $(AUTHENTICATORS) $(GSSSOURCES)
+libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h mx_imap.h \
+ message.c utf7.c util.c mx_imap.c $(AUTHENTICATORS) $(GSSSOURCES)
char mbox[LONG_STRING];
IMAP_MBOX mx;
- if (!mx_is_imap (path) || imap_parse_path (path, &mx)) {
+ if (mx_get_magic (path) == M_IMAP || imap_parse_path (path, &mx)) {
mutt_error (_("Bad mailbox name"));
return -1;
}
--- /dev/null
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mutt.h"
+#include "imap_private.h"
+
+#include "mx.h"
+#include "mx_imap.h"
+
+#include "lib/mem.h"
+#include "lib/str.h"
+
+#include "url.h"
+
+static int imap_is_magic (const char* path) {
+ url_scheme_t s;
+ if (!path || !*path)
+ return (-1);
+ if (*path == '{') /* pain\17pine compatibility */
+ return (M_IMAP);
+ s = url_check_scheme (NONULL (path));
+ return ((s == U_IMAP || s == U_IMAPS) ? M_IMAP : -1);
+}
+
+mx_t* imap_reg_mx (void) {
+ mx_t* fmt = safe_calloc (1, sizeof (mx_t));
+
+ /* make up mx_t record... */
+ fmt->type = M_IMAP;
+ fmt->mx_is_magic = imap_is_magic;
+ fmt->mx_access = imap_access;
+ fmt->mx_open_mailbox = imap_open_mailbox;
+ return (fmt);
+}
--- /dev/null
+
+/*
+ * interface of mx_t implementation for IMAP
+ */
+
+#ifndef _IMAP_MX_H
+#define _IMAP_MX_H
+
+#include "mx.h"
+
+mx_t* imap_reg_mx (void);
+
+#endif /* !_IMAP_MX_H */
tlen = safe_strlen (target.mbox);
/* check whether we can do '=' substitution */
- if (mx_is_imap (Maildir) && !imap_parse_path (Maildir, &home)) {
+ if (mx_get_magic (Maildir) == M_IMAP && !imap_parse_path (Maildir, &home)) {
hlen = safe_strlen (home.mbox);
if (tlen && mutt_account_match (&home.account, &target.account) &&
!safe_strncmp (home.mbox, target.mbox, hlen)) {
#endif
#ifdef USE_NNTP
-#include <nntp.h>
+#include "nntp/nntp.h"
#endif
static const char *ReachingUs = N_("\
start_curses ();
/* set defaults and read init files */
+ mx_init ();
mutt_init (flags & M_NOSYSRC, commands);
mutt_free_list (&commands);
- /* Initialize crypto backends. */
+ /* Initialize crypto */
crypt_init ();
if (queries)
mutt_expand_path (fpath, sizeof (fpath));
#ifdef USE_IMAP
/* we're not connected yet - skip mail folder creation */
- if (!mx_is_imap (fpath))
+ if (mx_get_magic (fpath) != M_IMAP)
#endif
if (stat (fpath, &sb) == -1 && errno == ENOENT) {
snprintf (msg, sizeof (msg), _("%s does not exist. Create it?"),
return ((st.st_size == 0));
}
+
+int mbox_is_magic (const char* path) {
+ struct stat st;
+ int magic = 0;
+ FILE* f;
+ char tmp[_POSIX_PATH_MAX];
+
+ if (stat (path, &st) == -1)
+ return (-1);
+
+ if (st.st_size == 0) {
+ /* hard to tell what zero-length files are, so assume the default magic */
+ if (DefaultMagic == M_MBOX || DefaultMagic == M_MMDF)
+ return (DefaultMagic);
+ else
+ return (M_MBOX);
+ }
+ else if ((f = fopen (path, "r")) != NULL) {
+#ifndef BUFFY_SIZE
+ struct utimbuf times;
+#endif
+ fgets (tmp, sizeof (tmp), f);
+ if (safe_strncmp ("From ", tmp, 5) == 0)
+ magic = M_MBOX;
+ else if (safe_strcmp (MMDF_SEP, tmp) == 0)
+ magic = M_MMDF;
+ safe_fclose (&f);
+#ifndef BUFFY_SIZE
+ /* need to restore the times here, the file was not really accessed,
+ * only the type was accessed. This is important, because detection
+ * of "new mail" depends on those times set correctly.
+ */
+ times.actime = st.st_atime;
+ times.modtime = st.st_mtime;
+ utime (path, ×);
+#endif
+ } else {
+ mutt_perror (path);
+ return (-1); /* fopen failed */
+ }
+
+#ifdef USE_COMPRESSED
+ if (magic == 0 && mutt_can_read_compressed (path))
+ return (M_COMPRESSED);
+#endif
+ return (magic);
+}
+
+static mx_t* reg_mx (void) {
+ mx_t* fmt = safe_calloc (1, sizeof (mx_t));
+ fmt->local = 1;
+ fmt->mx_check_empty = mbox_check_empty;
+ fmt->mx_is_magic = mbox_is_magic;
+ fmt->mx_access = access;
+ fmt->mx_open_mailbox = mbox_open_mailbox;
+ return (fmt);
+}
+
+mx_t* mbox_reg_mx (void) {
+ mx_t* fmt = reg_mx ();
+ fmt->type = M_MBOX;
+ return (fmt);
+}
+mx_t* mmdf_reg_mx (void) {
+ mx_t* fmt = reg_mx ();
+ fmt->type = M_MMDF;
+ return (fmt);
+}
int mmdf_parse_mailbox (CONTEXT *);
void mbox_unlock_mailbox (CONTEXT *);
int mbox_check_empty (const char *);
+int mbox_is_magic (const char*);
int mbox_strict_cmp_headers (const HEADER *, const HEADER *);
int mbox_reopen_mailbox (CONTEXT *, int *);
int mbox_open_new_message (MESSAGE * msg, CONTEXT * dest, HEADER * hdr);
+mx_t* mbox_reg_mx (void);
+mx_t* mmdf_reg_mx (void);
+
#endif
* subdir [IN] NULL for MH mailboxes, otherwise the subdir of the
* maildir mailbox to read from
*/
-int mh_read_dir (CONTEXT * ctx, const char *subdir)
+static int _mh_read_dir (CONTEXT * ctx, const char *subdir)
{
struct maildir *md;
struct mh_sequences mhs;
return 0;
}
+int mh_read_dir (CONTEXT* ctx) {
+ return (_mh_read_dir (ctx, NULL));
+}
+
/* read a maildir style mailbox */
int maildir_read_dir (CONTEXT * ctx)
{
/* maildir looks sort of like MH, except that there are two subdirectories
* of the main folder path from which to read messages
*/
- if (mh_read_dir (ctx, "new") == -1 || mh_read_dir (ctx, "cur") == -1)
+ if (_mh_read_dir (ctx, "new") == -1 || _mh_read_dir (ctx, "cur") == -1)
return (-1);
return 0;
return r;
}
+
+int mh_is_magic (const char* path) {
+ struct stat st;
+ char tmp[_POSIX_PATH_MAX];
+
+ if (stat (path, &st) == -1)
+ return (-1);
+
+ if (S_ISDIR (st.st_mode)) {
+ snprintf (tmp, sizeof (tmp), "%s/.mh_sequences", path);
+ if (access (tmp, F_OK) == 0)
+ return (M_MH);
+
+ snprintf (tmp, sizeof (tmp), "%s/.xmhcache", path);
+ if (access (tmp, F_OK) == 0)
+ return (M_MH);
+
+ snprintf (tmp, sizeof (tmp), "%s/.mew_cache", path);
+ if (access (tmp, F_OK) == 0)
+ return (M_MH);
+
+ snprintf (tmp, sizeof (tmp), "%s/.mew-cache", path);
+ if (access (tmp, F_OK) == 0)
+ return (M_MH);
+
+ snprintf (tmp, sizeof (tmp), "%s/.sylpheed_cache", path);
+ if (access (tmp, F_OK) == 0)
+ return (M_MH);
+
+ /*
+ * ok, this isn't an mh folder, but mh mode can be used to read
+ * Usenet news from the spool. ;-)
+ */
+
+ snprintf (tmp, sizeof (tmp), "%s/.overview", path);
+ if (access (tmp, F_OK) == 0)
+ return (M_MH);
+ }
+ return (-1);
+}
+
+int maildir_is_magic (const char* path) {
+ struct stat st;
+ char tmp[_POSIX_PATH_MAX];
+
+ if (stat (path, &st) == -1)
+ return (0);
+ if (S_ISDIR (st.st_mode)) {
+ snprintf (tmp, sizeof (tmp), "%s/cur", path);
+ if (stat (tmp, &st) == 0 && S_ISDIR (st.st_mode))
+ return (M_MAILDIR);
+ }
+ return (-1);
+}
+
+/* routines common to maildir and mh */
+static mx_t* reg_mx (void) {
+ mx_t* fmt = safe_calloc (1, sizeof (mx_t));
+ fmt->local = 1;
+ fmt->mx_access = access;
+ return (fmt);
+}
+
+mx_t* mh_reg_mx (void) {
+ mx_t* fmt = reg_mx ();
+ fmt->type = M_MH;
+ fmt->mx_check_empty = mh_check_empty;
+ fmt->mx_is_magic = mh_is_magic;
+ fmt->mx_open_mailbox = mh_read_dir;
+ return (fmt);
+}
+
+mx_t* maildir_reg_mx (void) {
+ mx_t* fmt = reg_mx ();
+ fmt->type = M_MAILDIR;
+ fmt->mx_check_empty = maildir_check_empty;
+ fmt->mx_is_magic = maildir_is_magic;
+ fmt->mx_open_mailbox = maildir_read_dir;
+ return (fmt);
+}
#include "mx.h"
-int mh_read_dir (CONTEXT *, const char *);
+int mh_read_dir (CONTEXT *);
int mh_sync_mailbox (CONTEXT *, int *);
int mh_check_mailbox (CONTEXT *, int *);
int mh_buffy (const char *);
int mh_check_empty (const char *);
+int mh_commit_message (CONTEXT *, MESSAGE *, HEADER *);
+int mh_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
+int mh_is_magic (const char*);
int maildir_read_dir (CONTEXT *);
int maildir_check_mailbox (CONTEXT *, int *);
int maildir_check_empty (const char *);
-
int maildir_commit_message (CONTEXT *, MESSAGE *, HEADER *);
-int mh_commit_message (CONTEXT *, MESSAGE *, HEADER *);
-
int maildir_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
-int mh_open_new_message (MESSAGE *, CONTEXT *, HEADER *);
-
FILE *maildir_open_find_message (const char *, const char *);
+int maildir_is_magic (const char*);
+
+mx_t* maildir_reg_mx (void);
+mx_t* mh_reg_mx (void);
#endif /* !_MH_H */
{
#ifdef USE_IMAP
/* if folder = {host} or imap[s]://host/: don't append slash */
- if (mx_is_imap (NONULL (Maildir)) &&
+ if (mx_get_magic (NONULL (Maildir)) == M_IMAP &&
(Maildir[safe_strlen (Maildir) - 1] == '}' ||
Maildir[safe_strlen (Maildir) - 1] == '/'))
strfcpy (p, NONULL (Maildir), sizeof (p));
#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))
+ if (mx_get_magic (s) == M_IMAP)
imap_expand_path (s, slen);
#endif
#endif
#ifdef USE_IMAP
-#include "imap.h"
+#include "imap/imap.h"
+#include "imap/mx_imap.h"
#endif
#ifdef USE_POP
-#include "pop.h"
+#include "pop/pop.h"
+#include "pop/mx_pop.h"
#endif
#ifdef USE_NNTP
-#include "nntp.h"
+#include "nntp/nntp.h"
+#include "nntp/mx_nntp.h"
#endif
#ifdef BUFFY_SIZE
#include "lib/mem.h"
#include "lib/intl.h"
#include "lib/str.h"
+#include "lib/list.h"
#include <dirent.h>
#include <fcntl.h>
#include <utime.h>
#endif
+static list2_t* MailboxFormats = NULL;
+#define MX_COMMAND(idx,cmd) ((mx_t*) MailboxFormats->data[idx])->cmd
#define mutt_is_spool(s) (safe_strcmp (Spoolfile, s) == 0)
#endif /* USE_DOTLOCK */
+/* looks up index of type for path in MailboxFormats */
+static int mx_get_idx (const char* path) {
+ int i = 0, t = 0;
+
+ for (i = 0; i < MailboxFormats->length; i++) {
+ t = MX_COMMAND(i,mx_is_magic)(path);
+ fprintf (stderr, " test %s for %i == %i\n", NONULL(path), i, t);
+ if (t >= 1)
+ return (t-1); /* use type as index for array */
+ }
+ return (-1);
+}
+
/* Args:
* excl if excl != 0, request an exclusive lock
* dot if dot != 0, try to dotlock the file
close (fd);
}
-/* try to figure out what type of mailbox ``path'' is
- *
- * return values:
- * M_* mailbox type
- * 0 not a mailbox
- * -1 error
- */
-
-#ifdef USE_IMAP
-int mx_is_imap (const char *p)
-{
- url_scheme_t scheme;
-
- if (!p)
- return 0;
-
- if (*p == '{')
- return 1;
-
- scheme = url_check_scheme (p);
- if (scheme == U_IMAP || scheme == U_IMAPS)
- return 1;
-
- return 0;
-}
-#endif
-
-#ifdef USE_POP
-int mx_is_pop (const char *p)
-{
- url_scheme_t scheme;
-
- if (!p)
- return 0;
-
- scheme = url_check_scheme (p);
- if (scheme == U_POP || scheme == U_POPS)
- return 1;
-
- return 0;
-}
-#endif
-
-#ifdef USE_NNTP
-int mx_is_nntp (const char *p)
-{
- url_scheme_t scheme;
-
- if (!p)
- return 0;
-
- scheme = url_check_scheme (p);
- if (scheme == U_NNTP || scheme == U_NNTPS)
- return 1;
-
- return 0;
-}
-#endif
-
-int mx_get_magic (const char *path)
-{
- struct stat st;
- int magic = 0;
- char tmp[_POSIX_PATH_MAX];
- FILE *f;
-
-#ifdef USE_IMAP
- if (mx_is_imap (path))
- return M_IMAP;
-#endif /* USE_IMAP */
-
-#ifdef USE_POP
- if (mx_is_pop (path))
- return M_POP;
-#endif /* USE_POP */
-
-#ifdef USE_NNTP
- if (mx_is_nntp (path))
- return M_NNTP;
-#endif /* USE_NNTP */
-
- if (stat (path, &st) == -1) {
- dprint (1,
- (debugfile, "mx_get_magic(): unable to stat %s: %s (errno %d).\n",
- path, strerror (errno), errno));
- return (-1);
- }
-
- if (S_ISDIR (st.st_mode)) {
- /* check for maildir-style mailbox */
-
- snprintf (tmp, sizeof (tmp), "%s/cur", path);
- if (stat (tmp, &st) == 0 && S_ISDIR (st.st_mode))
- return (M_MAILDIR);
-
- /* check for mh-style mailbox */
-
- snprintf (tmp, sizeof (tmp), "%s/.mh_sequences", path);
- if (access (tmp, F_OK) == 0)
- return (M_MH);
-
- snprintf (tmp, sizeof (tmp), "%s/.xmhcache", path);
- if (access (tmp, F_OK) == 0)
- return (M_MH);
-
- snprintf (tmp, sizeof (tmp), "%s/.mew_cache", path);
- if (access (tmp, F_OK) == 0)
- return (M_MH);
-
- snprintf (tmp, sizeof (tmp), "%s/.mew-cache", path);
- if (access (tmp, F_OK) == 0)
- return (M_MH);
-
- snprintf (tmp, sizeof (tmp), "%s/.sylpheed_cache", path);
- if (access (tmp, F_OK) == 0)
- return (M_MH);
-
- /*
- * ok, this isn't an mh folder, but mh mode can be used to read
- * Usenet news from the spool. ;-)
- */
-
- snprintf (tmp, sizeof (tmp), "%s/.overview", path);
- if (access (tmp, F_OK) == 0)
- return (M_MH);
-
- }
- else if (st.st_size == 0) {
- /* hard to tell what zero-length files are, so assume the default magic */
- if (DefaultMagic == M_MBOX || DefaultMagic == M_MMDF)
- return (DefaultMagic);
- else
- return (M_MBOX);
- }
- else if ((f = fopen (path, "r")) != NULL) {
-#ifndef BUFFY_SIZE
- struct utimbuf times;
-#endif
+/* try to figure out what type of mailbox ``path'' is */
+int mx_get_magic (const char *path) {
+ int i = 0;
- fgets (tmp, sizeof (tmp), f);
- if (safe_strncmp ("From ", tmp, 5) == 0)
- magic = M_MBOX;
- else if (safe_strcmp (MMDF_SEP, tmp) == 0)
- magic = M_MMDF;
- safe_fclose (&f);
-#ifndef BUFFY_SIZE
- /* need to restore the times here, the file was not really accessed,
- * only the type was accessed. This is important, because detection
- * of "new mail" depends on those times set correctly.
- */
- times.actime = st.st_atime;
- times.modtime = st.st_mtime;
- utime (path, ×);
-#endif
- }
- else {
- dprint (1,
- (debugfile,
- "mx_get_magic(): unable to open file %s for reading.\n", path));
- mutt_perror (path);
+ if (safe_strlen (path) == 0)
return (-1);
+ if ((i = mx_get_idx (path)) >= 0) {
+ fprintf (stderr, "%s is %i\n", NONULL(path), i);
+ return (MX_COMMAND(i,type));
}
-
-#ifdef USE_COMPRESSED
- if (magic == 0 && mutt_can_read_compressed (path))
- return M_COMPRESSED;
-#endif
-
- return (magic);
+ return (-1);
}
/*
* we use the normal access() flags. */
int mx_access (const char *path, int flags)
{
-#ifdef USE_IMAP
- if (mx_is_imap (path))
- return imap_access (path, flags);
-#endif
+ int i = 0;
- return access (path, flags);
+ if ((i = mx_get_idx (path)) >= 0 && MX_COMMAND(i,mx_access))
+ return (MX_COMMAND(i,mx_access)(path,flags));
+ return (0);
}
static int mx_open_mailbox_append (CONTEXT * ctx, int flags)
#ifdef USE_IMAP
- if (mx_is_imap (ctx->path))
+ if (mx_get_magic (ctx->path) == M_IMAP)
return imap_open_mailbox_append (ctx);
#endif
ctx->magic = mx_get_magic (path);
-#ifdef USE_COMPRESSED
if (ctx->magic == M_COMPRESSED)
mutt_open_read_compressed (ctx);
-#endif
if (ctx->magic == 0)
mutt_error (_("%s is not a mailbox."), path);
if (!ctx->quiet)
mutt_message (_("Reading %s..."), ctx->path);
- switch (ctx->magic) {
- case M_MH:
- rc = mh_read_dir (ctx, NULL);
- break;
-
- case M_MAILDIR:
- rc = maildir_read_dir (ctx);
- break;
-
- case M_MMDF:
- case M_MBOX:
- rc = mbox_open_mailbox (ctx);
- break;
-
-#ifdef USE_IMAP
- case M_IMAP:
- rc = imap_open_mailbox (ctx);
- break;
-#endif /* USE_IMAP */
-
-#ifdef USE_POP
- case M_POP:
- rc = pop_open_mailbox (ctx);
- break;
-#endif /* USE_POP */
-
-#ifdef USE_NNTP
- case M_NNTP:
- rc = nntp_open_mailbox (ctx);
- break;
-#endif /* USE_NNTP */
-
- default:
- rc = -1;
- break;
- }
+ if ((rc = mx_get_idx (ctx->path)) >= 0)
+ rc = MX_COMMAND(rc,mx_open_mailbox)(ctx);
if (rc == 0) {
if ((flags & M_NOSORT) == 0) {
/* try to use server-side copy first */
i = 1;
- if (ctx->magic == M_IMAP && mx_is_imap (mbox)) {
+ if (ctx->magic == M_IMAP && mx_get_magic (mbox) == M_IMAP) {
/* tag messages for moving, and clear old tags, if any */
for (i = 0; i < ctx->msgcount; i++)
if (ctx->hdrs[i]->read && !ctx->hdrs[i]->deleted
if (r == 0 && (ctx->magic == M_MBOX || ctx->magic == M_MMDF)
&& (fflush (msg->fp) == EOF || fsync (fileno (msg->fp)) == -1)) {
- mutt_perror _("Can't write message");
+ mutt_perror (_("Can't write message"));
r = -1;
}
*/
int mx_check_empty (const char *path)
{
- switch (mx_get_magic (path)) {
- case M_MBOX:
- case M_MMDF:
- return mbox_check_empty (path);
- case M_MH:
- return mh_check_empty (path);
- case M_MAILDIR:
- return maildir_check_empty (path);
- default:
- errno = EINVAL;
- return -1;
+ int i = 0;
+ if ((i = mx_get_idx (path)) >= 0 && MX_COMMAND(i,mx_check_empty))
+ return (MX_COMMAND(i,mx_check_empty)(path));
+ errno = EINVAL;
+ return (-1);
+}
+
+void mx_init (void) {
+#ifdef DEBUG
+ int i = 0;
+#endif
+ list_push_back (&MailboxFormats, (void*) mbox_reg_mx ());
+ list_push_back (&MailboxFormats, (void*) mmdf_reg_mx ());
+ list_push_back (&MailboxFormats, (void*) mh_reg_mx ());
+ list_push_back (&MailboxFormats, (void*) maildir_reg_mx ());
+#ifdef USE_IMAP
+ list_push_back (&MailboxFormats, (void*) imap_reg_mx ());
+#endif
+#ifdef USE_POP
+ list_push_back (&MailboxFormats, (void*) pop_reg_mx ());
+#endif
+#ifdef USE_NNTP
+ list_push_back (&MailboxFormats, (void*) nntp_reg_mx ());
+#endif
+#ifdef USE_COMPRESSED
+ list_push_back (&MailboxFormats, (void*) compress_reg_mx ());
+#endif
+#ifdef DEBUG
+ /* check module registration for completeness with debug versions */
+#define EXITWITHERR(m) do { fprintf(stderr, "error: incomplete mx module: %s is missing for type %i\n",m,i);exit(1); } while (0)
+ for (i = 0; i < MailboxFormats->length; i++) {
+ if (MX_COMMAND(i,type) < 1) EXITWITHERR("type");
+ if (!MX_COMMAND(i,mx_is_magic)) EXITWITHERR("mx_is_magic");
+ if (!MX_COMMAND(i,mx_open_mailbox)) EXITWITHERR("mx_open_mailbox");
}
- /* not reached */
+#undef EXITWITHERR
+#endif /* DEBUG */
}
#ifndef _MX_H
#define _MX_H
-/* supported mailbox formats */
+/*
+ * supported mailbox formats
+ * in mx_init() the registration order must be exactly as given here!!!1!
+ */
enum {
M_MBOX = 1,
M_MMDF,
#endif
};
+typedef struct {
+ /* folder magic */
+ int type;
+ /* may we stat() it? */
+ unsigned int local : 1;
+ /* tests if given path is of its magic */
+ int (*mx_is_magic) (const char*);
+ /* tests if folder is empty */
+ int (*mx_check_empty) (const char*);
+ /* test for access */
+ int (*mx_access) (const char*, int);
+ /* read mailbox into ctx structure */
+ int (*mx_open_mailbox) (CONTEXT*);
+} mx_t;
+
+/* called from main: init all folder types */
+void mx_init (void);
+
/* flags for mx_open_mailbox() */
#define M_NOSORT (1<<0) /* do not sort the mailbox after opening it */
#define M_APPEND (1<<1) /* open mailbox for appending messages */
int mx_set_magic (const char *);
int mx_check_mailbox (CONTEXT *, int *, int);
-#ifdef USE_IMAP
-int mx_is_imap (const char *);
-#endif
-#ifdef USE_POP
-int mx_is_pop (const char *);
-#endif
-#ifdef USE_NNTP
-int mx_is_nntp (const char *);
-#endif
-
int mx_access (const char *, int);
int mx_check_empty (const char *);
INCLUDES = -I$(top_srcdir) -I../intl
noinst_LIBRARIES = libnntp.a
-noinst_HEADERS = nntp.h
+noinst_HEADERS = nntp.h mx_nntp.h
-libnntp_a_SOURCES = nntp.c newsrc.c nntp.h
+libnntp_a_SOURCES = nntp.h mx_nntp.h \
+ nntp.c mx_nntp.c newsrc.c
--- /dev/null
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mutt.h"
+#include "nntp.h"
+
+#include "mx.h"
+#include "mx_nntp.h"
+
+#include "lib/mem.h"
+#include "lib/str.h"
+
+#include "url.h"
+
+static int nntp_is_magic (const char* path) {
+ url_scheme_t s = url_check_scheme (NONULL (path));
+ return ((s == U_NNTP || s == U_NNTPS) ? M_NNTP : -1);
+}
+
+/* called by nntp_init(); don't call elsewhere */
+mx_t* nntp_reg_mx (void) {
+ mx_t* fmt = safe_calloc (1, sizeof (mx_t));
+
+ /* make up mx_t record... */
+ fmt->type = M_NNTP;
+ fmt->mx_is_magic = nntp_is_magic;
+ fmt->mx_open_mailbox = nntp_open_mailbox;
+ return (fmt);
+}
--- /dev/null
+
+/*
+ * interface of mx_t implementation for NNTP
+ */
+
+#ifndef _NNTP_MX_H
+#define _NNTP_MX_H
+
+#include "mx.h"
+
+mx_t* nntp_reg_mx (void);
+
+#endif /* !_NNTP_MX_H */
#include "mutt_curses.h"
#include "sort.h"
#include "mx.h"
+#include "mx_nntp.h"
#include "mime.h"
#include "rfc1524.h"
#include "rfc2047.h"
if ((thepid = pgp_invoke_sign (&pgpin, &pgpout, &pgperr,
-1, -1, -1, signedfile)) == -1) {
- mutt_perror _("Can't open PGP subprocess!");
+ mutt_perror (_("Can't open PGP subprocess!"));
fclose (fp);
unlink (sigfile);
if ((thepid = pgp_invoke_traditional (&pgpin, NULL, NULL,
-1, fileno (pgpout), fileno (pgperr),
pgpinfile, keylist, flags)) == -1) {
- mutt_perror _("Can't invoke PGP");
+ mutt_perror (_("Can't invoke PGP"));
fclose (pgpout);
fclose (pgperr);
mutt_mktemp (tempfile);
if ((devnull = fopen ("/dev/null", "w")) == NULL) { /* __FOPEN_CHECKED__ */
- mutt_perror _("Can't open /dev/null");
+ mutt_perror (_("Can't open /dev/null"));
break;
}
if ((fp = safe_fopen (tempfile, "w")) == NULL) {
fclose (devnull);
- mutt_perror _("Can't create temporary file");
+ mutt_perror (_("Can't create temporary file"));
break;
}
if ((thepid = pgp_invoke_verify_key (NULL, NULL, NULL, -1,
fileno (fp), fileno (devnull),
tmpbuf)) == -1) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
unlink (tempfile);
fclose (fp);
}
if ((tempfp = safe_fopen (tempf, tempf == tempfb ? "w" : "a")) == NULL) {
- mutt_perror _("Can't create temporary file");
+ mutt_perror (_("Can't create temporary file"));
return NULL;
}
if ((devnull = fopen ("/dev/null", "w")) == NULL) { /* __FOPEN_CHECKED__ */
- mutt_perror _("Can't open /dev/null");
+ mutt_perror (_("Can't open /dev/null"));
fclose (tempfp);
if (tempf == tempfb)
if ((thepid =
pgp_invoke_export (NULL, NULL, NULL, -1,
fileno (tempfp), fileno (devnull), tmp)) == -1) {
- mutt_perror _("Can't create filter");
+ mutt_perror (_("Can't create filter"));
unlink (tempf);
fclose (tempfp);
INCLUDES = -I$(top_srcdir) -I../intl
noinst_LIBRARIES = libpop.a
-noinst_HEADERS = pop.h
+noinst_HEADERS = pop.h mx_pop.h
-libpop_a_SOURCES = pop.c pop_auth.c pop_lib.c pop.h
+libpop_a_SOURCES = pop.c pop_auth.c pop_lib.c pop.h mx_pop.h mx_pop.c
--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "mutt.h"
+#include "pop.h"
+
+#include "mx.h"
+#include "mx_pop.h"
+
+#include "lib/mem.h"
+#include "lib/str.h"
+
+#include "url.h"
+
+static int pop_is_magic (const char* path) {
+ url_scheme_t s = url_check_scheme (NONULL (path));
+ return ((s == U_POP || s == U_POPS) ? M_POP : -1);
+}
+
+mx_t* pop_reg_mx (void) {
+ mx_t* fmt = safe_calloc (1, sizeof (mx_t));
+
+ /* make up mx_t record... */
+ fmt->type = M_POP;
+ fmt->mx_is_magic = pop_is_magic;
+ fmt->mx_open_mailbox = pop_open_mailbox;
+ return (fmt);
+}
--- /dev/null
+
+/*
+ * interface of mx_t implementation for POP
+ */
+
+#ifndef _POP_MX_H
+#define _POP_MX_H
+
+#include "mx.h"
+
+mx_t* pop_reg_mx (void);
+
+#endif /* !_POP_MX_H */
#ifdef USE_IMAP
/* LastModify is useless for IMAP */
- if (mx_is_imap (Postponed)) {
+ if (mx_get_magic (Postponed) == M_IMAP) {
if (force) {
short newpc;
void mutt_paddstr (int, const char *);
void mutt_parse_mime_message (CONTEXT * ctx, HEADER *);
void mutt_parse_part (FILE *, BODY *);
-void mutt_perror (const char *);
+#define mutt_perror(a) _mutt_perror (a, __FILE__, __LINE__)
+void _mutt_perror (const char*, const char*,int);
void mutt_prepare_envelope (ENVELOPE *, int);
void mutt_unprepare_envelope (ENVELOPE *);
void mutt_pretty_mailbox (char *);
*/
#ifdef USE_IMAP
- if ((flags & SENDBATCH) && fcc[0] && mx_is_imap (fcc))
+ if ((flags & SENDBATCH) && fcc[0] && mx_get_magic (fcc) == M_IMAP)
fcc[0] = '\0';
#endif
if ((thepid = smime_invoke_sign (&smimein, NULL, &smimeerr,
-1, fileno (smimeout), -1,
filetosign)) == -1) {
- mutt_perror _("Can't open OpenSSL subprocess!");
+ mutt_perror (_("Can't open OpenSSL subprocess!"));
fclose (smimeout);
mutt_unlink (signedfile);