summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--lib/.cvsignore3
-rw-r--r--libproto/include/amd.h8
-rw-r--r--m4/.cvsignore2
-rw-r--r--mailbox/amd.c227
-rw-r--r--mailbox/mbx_default.c2
-rw-r--r--movemail/movemail.c1
7 files changed, 186 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index 6998a690b..f8752f39c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-05-31 Sergey Poznyakoff <gray@gnu.org.ua>
+
+ * libproto/include/amd.h (struct _amd_message.has_new_msg): New
+ field.
+ * mailbox/amd.c (amd_append_message): Cache information about
+ mailbox size in file .mu-size.
+ (make_size_file_name, read_size_file, write_size_file): New
+ functions.
+ (amd_expunge, amd_sync): Update size cache file.
+ (amd_get_size): Use size cache file if no mailbox_size method is
+ provided.
+ * mailbox/mbx_default.c (mu_normalize_mailbox_url): Accept `='
+ suffix for all mailbox types.
+ * movemail/movemail.c (main): Call mu_mailbox_sync before closing
+ destination mailbox.
+
2008-05-28 Sergey Poznyakoff <gray@gnu.org.ua>
* lib/Makefile.am (libmuaux_la_SOURCES): Add userprivs.c.
diff --git a/lib/.cvsignore b/lib/.cvsignore
index f10a4dfea..2d9fdfa36 100644
--- a/lib/.cvsignore
+++ b/lib/.cvsignore
@@ -109,6 +109,8 @@ printf-args.c
printf-args.h
printf-parse.c
printf-parse.h
+rawmemchr.c
+rawmemchr.valgrind
readlink.c
realloc.c
ref-add.sed
@@ -139,6 +141,7 @@ stdlib.h
stdlib.in.h
strcasecmp.c
strchrnul.c
+strchrnul.valgrind
strdup.c
streq.h
strerror.c
diff --git a/libproto/include/amd.h b/libproto/include/amd.h
index 2471b3d6f..e1f94376f 100644
--- a/libproto/include/amd.h
+++ b/libproto/include/amd.h
@@ -44,9 +44,9 @@ do \
struct _amd_data;
struct _amd_message
{
- mu_stream_t stream; /* Associated file stream */
- mu_off_t body_start; /* Offset of body start in the message file */
- mu_off_t body_end; /* Offset of body end (size of file, effectively)*/
+ mu_stream_t stream; /* Associated file stream */
+ mu_off_t body_start; /* Offset of body start in the message file */
+ mu_off_t body_end; /* Offset of body end (size of file, effectively)*/
int orig_flags; /* Original attribute flags */
int attr_flags; /* Current attribute flags */
@@ -84,7 +84,7 @@ struct _amd_data
struct _amd_message **msg_array;
unsigned long uidvalidity;
-
+ int has_new_msg; /* New messages have been appended */
char *name; /* Directory name */
/* Pool of open message streams */
diff --git a/m4/.cvsignore b/m4/.cvsignore
index e36910f7b..0df006035 100644
--- a/m4/.cvsignore
+++ b/m4/.cvsignore
@@ -71,7 +71,9 @@ memrchr.m4
openat.m4
pathmax.m4
po.m4
+printf.m4
progtest.m4
+rawmemchr.m4
readlink.m4
realloc.m4
regex.m4
diff --git a/mailbox/amd.c b/mailbox/amd.c
index 324cf288c..2d4c04c2b 100644
--- a/mailbox/amd.c
+++ b/mailbox/amd.c
@@ -767,6 +767,8 @@ amd_append_message (mu_mailbox_t mailbox, mu_message_t msg)
}
}
+ amd->has_new_msg = 1;
+
mhm->amd = amd;
if (amd->msg_init_delivery)
{
@@ -875,12 +877,142 @@ 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);
+ char *name = malloc (size);
+ if (name)
+ {
+ strcpy (name, amd->name);
+ strcat (name, "/");
+ strcat (name, SIZE_FILE_NAME);
+ }
+ return name;
+}
+
+static int
+read_size_file (struct _amd_data *amd, mu_off_t *psize)
+{
+ FILE *fp;
+ int rc;
+ char *name = make_size_file_name (amd);
+ if (!name)
+ return 1;
+ fp = fopen (name, "r");
+ if (fp)
+ {
+ unsigned long size;
+ if (fscanf (fp, "%lu", &size) == 1)
+ {
+ *psize = size;
+ rc = 0;
+ }
+ else
+ rc = 1;
+ fclose (fp);
+ }
+ free (name);
+ return rc;
+}
+
+static int
+write_size_file (struct _amd_data *amd, mu_off_t size)
+{
+ FILE *fp;
+ int rc;
+ char *name = make_size_file_name (amd);
+ if (!name)
+ return 1;
+ fp = fopen (name, "w");
+ if (fp)
+ {
+ fprintf (fp, "%lu", (unsigned long) size);
+ fclose (fp);
+ rc = 0;
+ }
+ else
+ rc = 1;
+ free (name);
+ return rc;
+}
+
+static int
+compute_mailbox_size (struct _amd_data *amd, const char *name, mu_off_t *psize)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char *buf;
+ size_t bufsize;
+ size_t dirlen;
+ size_t flen;
+ int status = 0;
+ struct stat sb;
+
+ dir = opendir (name);
+ if (!dir)
+ return errno;
+
+ dirlen = strlen (name);
+ bufsize = dirlen + 32;
+ buf = malloc (bufsize);
+ if (!buf)
+ {
+ closedir (dir);
+ return ENOMEM;
+ }
+
+ strcpy (buf, name);
+ if (buf[dirlen-1] != '/')
+ buf[++dirlen - 1] = '/';
+
+ while ((entry = readdir (dir)))
+ {
+ switch (entry->d_name[0])
+ {
+ case '.':
+ break;
+
+ default:
+ flen = strlen (entry->d_name);
+ if (dirlen + flen + 1 > bufsize)
+ {
+ bufsize = dirlen + flen + 1;
+ buf = realloc (buf, bufsize);
+ if (!buf)
+ {
+ status = ENOMEM;
+ break;
+ }
+ }
+ strcpy (buf + dirlen, entry->d_name);
+ if (stat (buf, &sb) == 0)
+ {
+ if (S_ISREG (sb.st_mode))
+ *psize += sb.st_size;
+ else if (S_ISDIR (sb.st_mode))
+ compute_mailbox_size (amd, buf, psize);
+ }
+ /* FIXME: else? */
+ break;
+ }
+ }
+
+ free (buf);
+
+ closedir (dir);
+ return 0;
+}
+
static int
amd_expunge (mu_mailbox_t mailbox)
{
struct _amd_data *amd = mailbox->data;
struct _amd_message *mhm;
size_t i;
+ int updated = amd->has_new_msg;
if (amd == NULL)
return EINVAL;
@@ -932,6 +1064,7 @@ amd_expunge (mu_mailbox_t mailbox)
free (old_name);
}
_amd_message_delete (amd, mhm);
+ updated = 1;
/* Do not increase i! */
}
else
@@ -941,11 +1074,19 @@ amd_expunge (mu_mailbox_t mailbox)
{
_amd_attach_message (mailbox, mhm, NULL);
_amd_message_save (amd, mhm, 1);
+ updated = 1;
}
i++; /* Move to the next message */
}
}
+ if (updated && !amd->mailbox_size)
+ {
+ mu_off_t size = 0;
+ int rc = compute_mailbox_size (amd, amd->name, &size);
+ if (rc == 0)
+ write_size_file (amd, size);
+ }
return 0;
}
@@ -955,6 +1096,7 @@ amd_sync (mu_mailbox_t mailbox)
struct _amd_data *amd = mailbox->data;
struct _amd_message *mhm;
size_t i;
+ int updated = amd->has_new_msg;
if (amd == NULL)
return EINVAL;
@@ -980,9 +1122,18 @@ amd_sync (mu_mailbox_t mailbox)
{
_amd_attach_message (mailbox, mhm, NULL);
_amd_message_save (amd, mhm, 0);
+ updated = 1;
}
}
+ if (updated && !amd->mailbox_size)
+ {
+ mu_off_t size = 0;
+ int rc = compute_mailbox_size (amd, amd->name, &size);
+ if (rc == 0)
+ write_size_file (amd, size);
+ }
+
return 0;
}
@@ -1193,80 +1344,20 @@ amd_is_updated (mu_mailbox_t mailbox)
}
static int
-compute_mailbox_size (const char *name, mu_off_t *psize)
-{
- DIR *dir;
- struct dirent *entry;
- char *buf;
- size_t bufsize;
- size_t dirlen;
- size_t flen;
- int status = 0;
- struct stat sb;
-
- dir = opendir (name);
- if (!dir)
- return errno;
-
- dirlen = strlen (name);
- bufsize = dirlen + 32;
- buf = malloc (bufsize);
- if (!buf)
- {
- closedir (dir);
- return ENOMEM;
- }
-
- strcpy (buf, name);
- if (buf[dirlen-1] != '/')
- buf[++dirlen - 1] = '/';
-
- while ((entry = readdir (dir)))
- {
- switch (entry->d_name[0])
- {
- case '.':
- break;
-
- default:
- flen = strlen (entry->d_name);
- if (dirlen + flen + 1 > bufsize)
- {
- bufsize = dirlen + flen + 1;
- buf = realloc (buf, bufsize);
- if (!buf)
- {
- status = ENOMEM;
- break;
- }
- }
- strcpy (buf + dirlen, entry->d_name);
- if (stat (buf, &sb) == 0)
- {
- if (S_ISREG (sb.st_mode))
- *psize += sb.st_size;
- else if (S_ISDIR (sb.st_mode))
- compute_mailbox_size (buf, psize);
- }
- /* FIXME: else? */
- break;
- }
- }
-
- free (buf);
-
- closedir (dir);
- return 0;
-}
-
-static int
amd_get_size (mu_mailbox_t mailbox, mu_off_t *psize)
{
struct _amd_data *amd = mailbox->data;
if (amd->mailbox_size)
return amd->mailbox_size (mailbox, psize);
*psize = 0;
- return compute_mailbox_size (amd->name, psize);
+ if (read_size_file (amd, psize))
+ {
+ int rc = compute_mailbox_size (amd, amd->name, psize);
+ if (rc == 0)
+ write_size_file (amd, *psize);
+ return rc;
+ }
+ return 0;
}
/* Return number of open streams residing in a message pool */
diff --git a/mailbox/mbx_default.c b/mailbox/mbx_default.c
index c0db199c8..60e742610 100644
--- a/mailbox/mbx_default.c
+++ b/mailbox/mbx_default.c
@@ -55,7 +55,7 @@ mu_normalize_mailbox_url (char **pout, const char *dir)
return MU_ERR_OUT_PTR_NULL;
len = strlen (dir);
- if (strncasecmp (dir, "mbox:", 5) == 0 && dir[len-1] == '=')
+ if (dir[len-1] == '=')
{
if (len > 5 && strcmp (dir + len - 5, "user=") == 0)
*pout = strdup (dir);
diff --git a/movemail/movemail.c b/movemail/movemail.c
index 72cf6328a..4dee71d61 100644
--- a/movemail/movemail.c
+++ b/movemail/movemail.c
@@ -419,6 +419,7 @@ main (int argc, char **argv)
if (rc)
return rc;
+ mu_mailbox_sync (dest);
rc = mu_mailbox_close (dest);
mu_mailbox_destroy (&dest);
if (rc)

Return to:

Send suggestions and report system problems to the System administrator.