Commit 00795731 007957314a3c82681d77ce4ffa1d7823fc0714f7 by Sergey Poznyakoff

Improve folder listing.

* include/mailutils/registrar.h (_mu_record): New method
`_list_p'.
(mu_record_list_p): New function.
* libproto/include/amd.h (MU_AMD_SIZE_FILE_NAME): New define.
* libproto/maildir/folder.c (_maildir_is_scheme): Return
MU_FOLDER_ATTRIBUTE_FILE|MU_FOLDER_ATTRIBUTE_DIRECTORY, on
success.
Implement _list_p method.
* libproto/mbox/folder.c (list_helper): Change semantics of the
2nd argument.  The record is used to determine whether or not
to list a particular file.
* libproto/mh/folder.c: Implement _list_p method.
* mailbox/amd.c (SIZE_FILE_NAME): Replace with
MU_AMD_SIZE_FILE_NAME from amd.h.
* mailbox/registrar.c (mu_record_list_p): New function.
1 parent 53b21b78
2008-08-17 Sergey Poznyakoff <gray@gnu.org.ua>
Improve folder listing.
* include/mailutils/registrar.h (_mu_record): New method
`_list_p'.
(mu_record_list_p): New function.
* libproto/include/amd.h (MU_AMD_SIZE_FILE_NAME): New define.
* libproto/maildir/folder.c (_maildir_is_scheme): Return
MU_FOLDER_ATTRIBUTE_FILE|MU_FOLDER_ATTRIBUTE_DIRECTORY, on
success.
Implement _list_p method.
* libproto/mbox/folder.c (list_helper): Change semantics of the
2nd argument. The record is used to determine whether or not
to list a particular file.
* libproto/mh/folder.c: Implement _list_p method.
* mailbox/amd.c (SIZE_FILE_NAME): Replace with
MU_AMD_SIZE_FILE_NAME from amd.h.
* mailbox/registrar.c (mu_record_list_p): New function.
Bugfix.
* libproto/maildir/mbox.c (info_to_flags): Fix return value.
Implement UNSELECT extension.
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2004, 2005, 2006,
2007 Free Software Foundation, Inc.
2007, 2008 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -43,6 +43,8 @@ struct _mu_record
int (*_get_mailbox) (mu_record_t, int (*(*_mu_mailbox)) (mu_mailbox_t));
int (*_get_mailer) (mu_record_t, int (*(*_mu_mailer)) (mu_mailer_t));
int (*_get_folder) (mu_record_t, int (*(*_mu_folder)) (mu_folder_t));
int (*_list_p) (mu_record_t, const char *, int);
};
/* Registration. */
......@@ -84,6 +86,8 @@ extern int mu_record_set_folder (mu_record_t, int (*) (mu_folder_t));
extern int mu_record_set_get_folder (mu_record_t,
int (*_get_folder) (mu_record_t, int (*(*)) (mu_folder_t)));
extern int mu_record_list_p (mu_record_t record, const char *name, int);
/* Records provided by the library. */
/* Remote Folder "imap://" */
......
......@@ -42,6 +42,8 @@
mu_monitor_wrlock (mbox->monitor); \
} while (0);
#define MU_AMD_SIZE_FILE_NAME ".mu-size"
struct _amd_data;
struct _amd_message
{
......
......@@ -81,11 +81,20 @@ _maildir_is_scheme (mu_record_t record, mu_url_t url, int flags)
&& dir_exists (path, TMPSUF)
&& dir_exists (path, CURSUF)
&& dir_exists (path, NEWSUF))
return MU_FOLDER_ATTRIBUTE_FILE;
return MU_FOLDER_ATTRIBUTE_FILE|MU_FOLDER_ATTRIBUTE_DIRECTORY;
}
return 0;
}
static int
_maildir_list_p (mu_record_t record, const char *name, int flags MU_ARG_UNUSED)
{
return strcmp (name, TMPSUF)
&& strcmp (name, CURSUF)
&& strcmp (name, NEWSUF)
&& strcmp (name, MU_AMD_SIZE_FILE_NAME);
}
static struct _mu_record _maildir_record =
{
MU_MAILDIR_PRIO,
......@@ -99,7 +108,8 @@ static struct _mu_record _maildir_record =
NULL, /* _get_url method. */
NULL, /* _get_mailbox method. */
NULL, /* _get_mailer method. */
NULL /* _get_folder method. */
NULL, /* _get_folder method. */
_maildir_list_p
};
mu_record_t mu_maildir_record = &_maildir_record;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001, 2003, 2004,
2005, 2006, 2007 Free Software Foundation, Inc.
2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
......@@ -337,6 +337,13 @@ list_helper (struct search_data *data, mu_record_t record,
data->errcnt++;
return 1;
}
if (!record)
{
int type;
mu_registrar_lookup (dirname, MU_FOLDER_ATTRIBUTE_ALL,
&record, &type);
}
while ((dp = readdir (dirp)))
{
......@@ -349,97 +356,94 @@ list_helper (struct search_data *data, mu_record_t record,
fname = get_pathname (dirname, ename);
if (stat (fname, &st) == 0)
{
if (data->folder->_match == NULL
|| data->folder->_match (fname + data->dirlen +
((data->dirlen > 1
&& data->dirname[data->dirlen-1] != '/') ?
1 : 0),
data->pattern,
data->flags) == 0)
int f;
if (S_ISDIR (st.st_mode))
f = MU_FOLDER_ATTRIBUTE_DIRECTORY;
else if (S_ISREG (st.st_mode))
f = MU_FOLDER_ATTRIBUTE_FILE;
else
f = 0;
if (mu_record_list_p (record, ename, f))
{
char *refname = fname;
int type = 0;
struct mu_list_response *resp;
resp = malloc (sizeof (*resp));
if (resp == NULL)
if (data->folder->_match == NULL
|| data->folder->_match (fname + data->dirlen +
((data->dirlen > 1
&& data->dirname[data->dirlen-1] != '/') ?
1 : 0),
data->pattern,
data->flags) == 0)
{
MU_DEBUG1 (data->folder->debug, MU_DEBUG_ERROR,
"list_helper: %s", mu_strerror (ENOMEM));
data->errcnt++;
free (fname);
continue;
}
if (record)
{
mu_url_t url;
int rc = mu_url_create (&url, refname);
if (rc == 0)
char *refname = fname;
int type = 0;
struct mu_list_response *resp;
mu_record_t rec = NULL;
resp = malloc (sizeof (*resp));
if (resp == NULL)
{
rc = mu_url_parse (url);
if (rc == 0)
type = mu_record_is_scheme (record, url,
MU_FOLDER_ATTRIBUTE_ALL);
MU_DEBUG1 (data->folder->debug, MU_DEBUG_ERROR,
"list_helper: %s", mu_strerror (ENOMEM));
data->errcnt++;
free (fname);
continue;
}
mu_url_destroy (&url);
}
else
mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL,
&record, &type);
resp->name = fname;
resp->level = level;
resp->separator = '/';
resp->type = type;
if (resp->type == 0)
{
free (resp->name);
free (resp);
continue;
}
if (data->enumfun)
{
if (data->enumfun (data->folder, resp, data->enumdata))
mu_registrar_lookup (refname, MU_FOLDER_ATTRIBUTE_ALL,
&rec, &type);
resp->name = fname;
resp->level = level;
resp->separator = '/';
resp->type = type;
if (resp->type == 0)
{
free (resp->name);
free (resp);
stop = 1;
break;
continue;
}
if (data->enumfun)
{
if (data->enumfun (data->folder, resp, data->enumdata))
{
free (resp->name);
free (resp);
stop = 1;
break;
}
}
if (data->result)
{
fname = NULL;
mu_list_append (data->result, resp);
}
else
free (resp);
if ((type & MU_FOLDER_ATTRIBUTE_DIRECTORY)
&& !inode_list_lookup (ilist, &st))
{
struct inode_list idata;
idata.inode = st.st_ino;
idata.dev = st.st_dev;
idata.next = ilist;
stop = list_helper (data, rec, refname, level + 1,
&idata);
}
}
if (data->result)
{
fname = NULL;
mu_list_append (data->result, resp);
}
else
free (resp);
if ((type & MU_FOLDER_ATTRIBUTE_DIRECTORY)
&& !inode_list_lookup (ilist, &st))
else if (S_ISDIR (st.st_mode))
{
struct inode_list idata;
idata.inode = st.st_ino;
idata.dev = st.st_dev;
idata.next = ilist;
stop = list_helper (data, record, refname, level + 1,
&idata);
stop = list_helper (data, NULL, fname, level + 1, &idata);
}
}
else if (S_ISDIR (st.st_mode))
{
struct inode_list idata;
idata.inode = st.st_ino;
idata.dev = st.st_dev;
idata.next = ilist;
stop = list_helper (data, NULL, fname, level + 1, &idata);
}
}
else
{
......
......@@ -119,6 +119,22 @@ _mh_is_scheme (mu_record_t record, mu_url_t url, int flags)
return 0;
}
static int
_mh_list_p (mu_record_t record, const char *name, int flags MU_ARG_UNUSED)
{
int len;
if (strcmp (name, MU_AMD_SIZE_FILE_NAME) == 0
|| name[0] == ','
|| (((len = strlen (name)) > 3) && memcmp (name, ".mh", 3) == 0))
return 0;
for (; *name; name++)
if (!(isascii (*name) && isdigit (*name)))
return 1;
return 0;
}
static struct _mu_record _mh_record =
{
MU_MH_PRIO,
......@@ -132,7 +148,8 @@ static struct _mu_record _mh_record =
NULL, /* _get_url method. */
NULL, /* _get_mailbox method. */
NULL, /* _get_mailer method. */
NULL /* _get_folder method. */
NULL, /* _get_folder method. */
_mh_list_p
};
mu_record_t mu_mh_record = &_mh_record;
......
......@@ -883,18 +883,16 @@ amd_message_unseen (mu_mailbox_t mailbox, size_t *pmsgno)
return 0;
}
#define SIZE_FILE_NAME ".mu-size"
static char *
make_size_file_name (struct _amd_data *amd)
{
size_t size = strlen (amd->name) + 1 + sizeof (SIZE_FILE_NAME);
size_t size = strlen (amd->name) + 1 + sizeof (MU_AMD_SIZE_FILE_NAME);
char *name = malloc (size);
if (name)
{
strcpy (name, amd->name);
strcat (name, "/");
strcat (name, SIZE_FILE_NAME);
strcat (name, MU_AMD_SIZE_FILE_NAME);
}
return name;
}
......
......@@ -339,3 +339,13 @@ mu_record_set_get_folder (mu_record_t record,
record->_get_folder = _get_folder;
return 0;
}
int
mu_record_list_p (mu_record_t record, const char *name, int flags)
{
if (record == NULL)
return EINVAL;
return record == NULL
|| !record->_list_p
|| record->_list_p (record, name, flags);
}
......