Commit 149583b5 149583b547636023968c738295a0042e7cd80174 by Alain Magloire

* configure.in: Set to 0.0.9c.

	* doc/texinfo/mbox.texi: Update the doc for mbox(Unix).
	* doc/texinfo/pop.texi: Update the doc for mbox(Unix).

	* imap4d/expunge.c: Bug:  Expunge was not sending the
	untag "* %d EXPUNGED" for message deleted.  Call imap4d_sync ()
	which will do the right thing.
	* imap4d/noop.c: Bug: It should call imap4d_sync () to notify
	the client of any changes.
	* imap4d/sync.c (notify_deleted): Typo should be EXPUNGED
	with a D.
	(imap4d_sync): Bug: Checked also if the number of messages changed.

	* mailbox/folder_imap.c (imap_flags): Bug: Rewrite it to be generic
	and sets the flags for the attribute.
	(imap_fetch_flags): Call imap_flags().
	(imap_permanentflags): Call imap_flags().

	* mailbox2/include/mailutils/mbox.h: Update prototypes.
	* mailbox2/include/mailutils/sys/mbox.h: Update prototypes.
	* mailbox2/include/mailutils/pop3.h: Update prototypes.
	* mailbox2/mbox/mbox_expunge.c (mbox_expunge): Calls mbox_expunge0 ().
	(mbox_save): Calls mbox_expunge0().
	* mailbox2/mbox/mbox_scan.c (mbox_scan): Calls mbox_scan0 ().
	(mbox_count): Calls mbox_scan0().
	* mailbox2/pop3/pop3_capa.c: Provide a special iterator.
	* mailbox2/pop3/pop3_lista.c: Provide a special iterator.
	* mailbox2/pop3/pop3_uidla.c: Provide a special iterator.
1 parent bd6da6fc
2001-10-20 Alain Magloire
* configure.in: Set to 0.0.9c.
* doc/texinfo/mbox.texi: Update the doc for mbox(Unix).
* doc/texinfo/pop.texi: Update the doc for mbox(Unix).
* imap4d/expunge.c: Bug: Expunge was not sending the
untag "* %d EXPUNGED" for message deleted. Call imap4d_sync ()
which will do the right thing.
* imap4d/noop.c: Bug: It should call imap4d_sync () to notify
the client of any changes.
* imap4d/sync.c (notify_deleted): Typo should be EXPUNGED
with a D.
(imap4d_sync): Bug: Checked also if the number of messages changed.
* mailbox/folder_imap.c (imap_flags): Bug: Rewrite it to be generic
and sets the flags for the attribute.
(imap_fetch_flags): Call imap_flags().
(imap_permanentflags): Call imap_flags().
* mailbox2/include/mailutils/mbox.h: Update prototypes.
* mailbox2/include/mailutils/sys/mbox.h: Update prototypes.
* mailbox2/include/mailutils/pop3.h: Update prototypes.
* mailbox2/mbox/mbox_expunge.c (mbox_expunge): Calls mbox_expunge0 ().
(mbox_save): Calls mbox_expunge0().
* mailbox2/mbox/mbox_scan.c (mbox_scan): Calls mbox_scan0 ().
(mbox_count): Calls mbox_scan0().
* mailbox2/pop3/pop3_capa.c: Provide a special iterator.
* mailbox2/pop3/pop3_lista.c: Provide a special iterator.
* mailbox2/pop3/pop3_uidla.c: Provide a special iterator.
2001-10-19 Sergey Poznyakoff
MH inc is fully functional:
......@@ -11,7 +43,7 @@
2001-10-19 Sergey Poznyakoff
Implemented saving of MH context.
Implemented saving of MH context.
* mh/inc.c: Fixed truncate option. Implemented -changecur. The only
feature inc lacks so far is -audit.
......@@ -23,13 +55,13 @@
New functions: mh_save_context, mh_write_context_file, mh_check_folder,
mh_getyn.
* mh/mh.h: Prototypes for new functions.
2001-10-17 Sam Roberts
* README-alpha : Update cvs repository path.
2001-10-17 Sergey Poznyakoff
After discussion with Jeff, removed maintainer-mode quirks
and introduced --enable-debug switch.
......
dnl Process this file with autoconf to procude a configure script.
AC_INIT(mailbox/mailbox.c)
AM_INIT_AUTOMAKE(mailutils, 0.0.9b)
AM_INIT_AUTOMAKE(mailutils, 0.0.9c)
AM_CONFIG_HEADER(config.h)
dnl Check for programs
......
......@@ -4,7 +4,11 @@
@end example
Internet Message Access Protocol - Version (4rev1). Not implemented.
Internet Message Access Protocol - Version (4rev1). In IMAP the client
must be prepared to accept any responses at all times. The server responses
have three forms: status reponses, server data and command continuation
request. Untaged responses, for hitorical reasons are also call
"unsolicited responses".
@subsection Commands
......
......@@ -4,8 +4,8 @@
@end example
The most common mailbox format on UNIX platform is @emph{mbox}. Mbox file
is messages separated by the special format string.
The most common mailbox format on UNIX platform is @emph{mbox}. Mbox is a
text file that contains messages separated by a special format string.
@example
From SP envelope-sender SP date [SP moreinfo]
@end example
......@@ -24,15 +24,16 @@ is messages separated by the special format string.
A @var{mbox_t} is created, initialized and destroyed by @code{mbox_create ()}
and @code{mbox_destroy ()}. When opening, @code{mbox_open ()} will do a quick
check to see if the format is a valid format or an empty file. The scanning
of the mailbox is done by @code{mbox_scan ()}.
The function, @code{mbox_scan ()}, takes callback functions called during the
scanning to provide information. The scanning will cache some of the headers
fields for speed. Closing the mailbox, @code{mbox_close ()} will free
any resources like, headers cache, locks etc ... All the messages with
attributes marked deleted will only be removed on @code{mbox_expunge ()}.
If only the attributes need to be save but the messages not removed, this
can be done by @code{mbox_save_attributes ()}. New messages are added with
@code{mbox_append ()}. Attributes are saved in the @emph{Status:} header
of the mailbox is done by @code{mbox_scan ()}, the function, takes callback
functions called during the scanning to provide information on progress and
new messages found. The scanning will cache some of the headers fields for
speed, new fields could be add with @code{mbox_add_hcache ()}. On Closing
the @var{mbox_t}, @code{mbox_close ()} will free any resources like, headers
cache, locks etc ... The messages with attributes marked deleted will only
be removed on @code{mbox_expunge ()}, if there is a need to save the
modification without purging @code{mbox_save ()} is more appropriate.
New messages are added to the mbox with @code{mbox_append ()}.
Attributes are saved in the @emph{Status:} header
field, Read is 'R', Seen is 'O', Deleted is 'd' and Reply is 'r'.
@subsubsection Initialization
......@@ -59,9 +60,9 @@ reclaim memory.
@deftypefun int mbox_set_carrier (mbox_t, stream_t @var{carrier});
Another type of stream can be provided to work on, the @var{carrier}
Another type of stream can be provided, the @var{carrier}
is set in the @var{mbox_t} handle. Any previous @var{carrier} stream in
the handle, will be close and release. Since the parsing code
the handle, will be close and destroy. Since the parsing code
maintain only the offsets off the message the @var{carrier} stream must be
seekable.
......@@ -127,6 +128,15 @@ is called first.
@end table
@end deftypefun
@deftypefun int mbox_get_uid (mbox_t, unsigned int @var{msgno}, unsigned long *@var{uid})
Return the @var{uid} of the message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_get_attribute (mbox_t, unsigned int @var{msgno}, attribute_t *@var{attribute})
Return an @var{attribute} to indicate the status of message number @var{msgno}.
......@@ -245,28 +255,43 @@ Return the @var{size} of mailbox.
@end table
@end deftypefun
@deftypefun int mbox_save (mbox_t)
@deftypefun int mbox_set_hcache (mbox_t, const char **@var{array}, size_t @var{len})
Save the changes to the messages back to the mailbox, but do not
remove messages mark for deletion in the process.
Set the @var{array} of fields as the header to cache when doing the scanning.
If @var{array} is NULL the header cache is emptied.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_add_hcache (mbox_t, const char **@var{array}, size_t @var{len})
Add to the current cache for the scan, the fields in @var{array}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_mak_deleted (mbox_t, unsigned int @var{msgno})
@deftypefun int mbox_value_hcache (mbox_t, unsigned int @var{msgno}, const char *@var{field}, char *@var{buffer}, size_t @var{buflen}, size_t *@var{writen})
Mark @var{msgno} for deletion.
Get the value of @var{field} in the header cache for @var{msgno}. The
result is copied in a @var{buffer} of @var{buflen} and @var{writen} is set
to the number of byte put in @var{buffer}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_ENTRY
@end table
@end deftypefun
@deftypefun int mbox_unmak_deleted (mbox_t, unsigned int @var{msgno})
@deftypefun int mbox_save (mbox_t)
Unmark @var{msgno} if it was marked for deletion.
Save the changes to the messages back to the mailbox, but do not
remove messages mark for deletion in the process.
@table @code
@item MU_ERROR_INVALID_PARAMETER
......@@ -305,7 +330,7 @@ and a body, @var{bstream}. The variable @var{sep} should contain a valid
@end table
@end deftypefun
@deftypefun int mbox_scan (mbox_t, unsigned int start, unsigned int *@var{count})
@deftypefun int mbox_scan (mbox_t, unsigned int @var{start}, unsigned int *@var{count})
Start scanning the mailbox for new messages. The variable @var{start} can be
a message number starting point. The result of the scanning will be in
......@@ -322,21 +347,43 @@ MU_ERROR_INTERRUPTED.
@end table
@end deftypefun
@deftypefun int mbox_set_progress_cb (mbox_t, int (*@var{callback}) (int, void *)), void *@var{arg})
@deftypefun int mbox_count (mbox_t, unsigned int *@var{count})
Same as @code{mbox_scan ()} but does not call the callbacks.
@end deftypefun
@deftypefun int mbox_set_progress_cb (mbox_t, int (*@var{callback}) (int @var{percentage}, void *)), void *@var{arg})
Set the callback function for progress. The variable @var{arg} will be pass
back in the callback as the second argument.
back in the callback as the second argument. The first argument of the
callback represents a @var{percentage} of the scanning progress.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_newmsg_cb (mbox_t, int (*@var{callback}) (int, void *)), void *@var{arg})
@deftypefun int mbox_set_newmsg_cb (mbox_t, int (*@var{callback}) (int @var{count}, void *)), void *@var{arg})
Set the callback function for new messages. The variable @var{arg} will be
pass back in the callback as the second argument. The first argument
is the total of messages found.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_error_cb (mbox_t, int (*@var{callback}) (int, void *)), void *@var{arg})
Set the callback function for errors. The variable @var{arg} will be
pass back in the callback as the second argument.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_has_newmail (mbox_t)
Return nonzero if there is new mail append to the mbox_t.
@end deftypefun
......
......@@ -81,9 +81,8 @@ means only one operation can be done at a time, all the functions will return
MU_ERROR_OPERATION_IN_PROGRESS if call during another operation. The
functions @code{pop3_list_all ()}, @code{pop3_uidl_all ()} and
@code{pop3_capa ()} return iterators @code{pop3_list_current ()},
@code{pop3_uidl_current ()} are provided as cover function to format the
string return by @code{iterator_current ()}, @code{iterator_destroy ()} must
be call to release any resources.
@code{pop3_uidl_current ()} are provided as cover function. The iterator must
be destroy when finish.
In a multithreaded application, only one thread should access @var{pop3_t}
handles.
......@@ -197,16 +196,16 @@ any remaining responses from CAPA and clear the way for new operations.
void print_capabilities (pop3_t pop3)
@{
iterator_t iterator;
pop3_capa_iterator_t iterator;
status = pop3_capa (pop3, &iterator);
if (status == 0)
@{
for (iterator_first (iterator);
!iterator_is_done (iterator);
iterator_next (iterator))
for (pop3_capa_first (iterator);
!pop3_capa_is_done (iterator);
pop3_capa_next (iterator))
@{
char *capa;
if (iterator_current (iterator, &capa) == 0)
if (pop3_capa_current (iterator, &capa) == 0)
@{;
printf ("CAPA: %s\n", capa);
free (capa);
......@@ -272,13 +271,13 @@ around to scan properly the string return by the @code{iterator_current ()}.
void print_list (pop3_t pop3)
@{
iterator_t iterator;
pop3_list_iterator_t iterator;
status = pop3_list_all (pop3, &iterator);
if (status == 0)
@{
for (iterator_first (iterator);
!iterator_is_done (iterator);
iterator_next (iterator))
for (pop3_list_first (iterator);
!pop3_list_is_done (iterator);
pop3_list_next (iterator))
@{
unsigned int msgno, size;
if (pop3_list_current (iterator, &msgno, &size) == 0)
......@@ -286,7 +285,7 @@ void print_list (pop3_t pop3)
printf ("LIST: %d %d\n", msgno, size);
@}
@}
iterator (&iterator);
pop3_list_destroy (&iterator);
@}
else
printf ("NONE\n");
......@@ -392,7 +391,7 @@ print_message (pop3_t pop3, unsigned int msgno)
while ((stream_readline (stream, buf, sizeof buf, &n) == 0)
&& n)
printf ("%s", buf);
stream_release (stream);
stream_destroy (&stream);
@}
return status;
@}
......@@ -466,7 +465,7 @@ print_top (pop3_t pop3, unsigned int msgno, unsigned int lines)
while ((stream_readline (stream, buf, sizeof buf, &n) == 0)
&& n)
printf ("%s", buf);
stream_release (stream);
stream_destroy (&stream);
@}
return status;
@}
......@@ -510,13 +509,13 @@ must be destroyed by the caller.
void print_uidl (pop3_t pop3)
@{
iterator_t iterator;
pop3_uidl_iterator_t iterator;
status = pop3_uidl_all (pop3, &iterator);
if (status == 0)
@{
for (iterator_first (iterator);
!iterator_is_done (iterator);
iterator_next (iterator))
for (pop3_uidl_first (iterator);
!pop3_uidl_is_done (iterator);
pop3_uidl_next (iterator))
@{
unsigned int msgno;
char *uidl;
......@@ -526,7 +525,7 @@ void print_uidl (pop3_t pop3)
free (uidl);
@}
@}
iterator (&iterator);
pop3_uidl_destroy (&iterator);
@}
else
printf ("NONE\n");
......@@ -577,8 +576,9 @@ Sends the User command.
@deftypefun int pop3_writeline (pop3_t, const char *@var{format}, ...);
Copy in the internal buffer of @code{pop3_t} the string, @code{pop3_send ()}
should be called later to flush the string to the POP3 server.
Copy in the internal buffer of @code{pop3_t} the formatted string,
@code{pop3_send ()} should be called later to flush the string to the
POP3 server.
@table @code
@item MU_ERROR_INVALID_PARAMETER
......
......@@ -25,6 +25,7 @@ int
imap4d_expunge (struct imap4d_command *command, char *arg)
{
char *sp = NULL;
if (! (command->states & state))
return util_finish (command, RESP_BAD, "Wrong state");
if (util_getword (arg, &sp))
......@@ -32,5 +33,7 @@ imap4d_expunge (struct imap4d_command *command, char *arg)
/* FIXME: check for errors. */
mailbox_expunge (mbox);
imap4d_sync ();
return util_finish (command, RESP_OK, "Completed");
}
......
......@@ -22,10 +22,12 @@ int
imap4d_noop (struct imap4d_command *command, char *arg)
{
char *sp = NULL;
if (! (command->states & state))
return util_finish (command, RESP_BAD, "Wrong state");
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
imap4d_select_status();
imap4d_sync ();
return util_finish (command, RESP_OK, "Completed");
}
......
......@@ -113,7 +113,7 @@ notify_deleted (void)
{
if (!(uid_table[i].notify))
{
util_out (RESP_NONE, "%d EXPUNGE", uid_table[i].msgno);
util_out (RESP_NONE, "%d EXPUNGED", uid_table[i].msgno);
uid_table[i].notify = 1;
}
}
......@@ -175,8 +175,8 @@ free_uids (void)
attribute_destroy (&(uid_table[i].attr), NULL);
free (uid_table);
uid_table = NULL;
uid_table_count = 0;
}
uid_table_count = 0;
}
static void
......@@ -240,11 +240,19 @@ imap4d_sync_flags (size_t msgno)
int
imap4d_sync (void)
{
/* if mbox --> NULL, it means to free all the ressources.
it may be because of close or before select/examine a new mailbox. */
/* If mbox --> NULL, it means to free all the ressources.
It may be because of close or before select/examine a new mailbox.
If it was a close we do not send any notification. */
if (mbox == NULL)
free_uids ();
else if (uid_table == NULL || !mailbox_is_updated (mbox))
reset_uids ();
else
{
size_t count = 0;
mailbox_messages_count (mbox, &count);
if (count != uid_table_count)
reset_uids ();
}
return 0;
}
......
......@@ -91,7 +91,9 @@ static int imap_rfc822 __P ((f_imap_t, char **));
static int imap_rfc822_size __P ((f_imap_t, char **));
static int imap_rfc822_header __P ((f_imap_t, char **));
static int imap_rfc822_text __P ((f_imap_t, char **));
static int imap_flags __P ((f_imap_t, char **));
static int imap_fetch_flags __P ((f_imap_t, char **));
static int imap_permanentflags __P ((f_imap_t, char **));
static int imap_flags __P ((char **, int *));
static int imap_bodystructure __P ((f_imap_t, char **));
static int imap_body __P ((f_imap_t, char **));
static int imap_internaldate __P ((f_imap_t, char **));
......@@ -1266,12 +1268,27 @@ imap_bodystructure (f_imap_t f_imap, char **ptr)
FIXME: User flags are not take to account. */
static int
imap_flags (f_imap_t f_imap, char **ptr)
imap_fetch_flags (f_imap_t f_imap, char **ptr)
{
msg_imap_t msg_imap = f_imap->string.msg_imap;
if (msg_imap)
imap_flags (ptr, &msg_imap->flags);
return 0;
}
static int
imap_permanentflags (f_imap_t f_imap, char **ptr)
{
imap_flags (ptr, &f_imap->flags);
return 0;
}
static int
imap_flags (char **ptr, int *pflags)
{
char *start;
char *end;
/* msg_imap may be null for an untag response deal with it. */
msg_imap_t msg_imap = f_imap->string.msg_imap;
int flags = 0;
/* Skip space. */
while (**ptr == ' ')
......@@ -1286,65 +1303,52 @@ imap_flags (f_imap_t f_imap, char **ptr)
{
/* Skip space before next word. */
while (**ptr == ' ')
(*ptr)++;
(*ptr)++;
/* Save the beginning of the word. */
start = *ptr;
/* Get the next word boundary. */
/* Get the next word boundary. */
while (**ptr && **ptr != ' ' && **ptr != ')')
++(*ptr);
++(*ptr);
/* Make a C string for the strcasecmp. */
/* Save the end for the strcasecmp. */
end = *ptr;
/* Bail out. */
if (*start == '\0')
break;
break;
/* Guess the flag. */
if (strncasecmp (start, "\\Seen", end - start) == 0)
{
if (msg_imap)
{
msg_imap->flags |= MU_ATTRIBUTE_SEEN;
msg_imap->flags |= MU_ATTRIBUTE_READ;
}
else
f_imap->flags |= MU_ATTRIBUTE_SEEN;
}
{
flags |= MU_ATTRIBUTE_SEEN;
flags |= MU_ATTRIBUTE_READ;
}
else if (strncasecmp (start, "\\Answered", end - start) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_ANSWERED;
else
f_imap->flags |= MU_ATTRIBUTE_ANSWERED;
}
{
flags |= MU_ATTRIBUTE_ANSWERED;
}
else if (strncasecmp (start, "\\Flagged", end - start) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_FLAGGED;
else
f_imap->flags |= MU_ATTRIBUTE_FLAGGED;
}
{
flags |= MU_ATTRIBUTE_FLAGGED;
}
else if (strncasecmp (start, "\\Deleted", end - start) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_DELETED;
else
f_imap->flags |= MU_ATTRIBUTE_DELETED;
}
{
flags |= MU_ATTRIBUTE_DELETED;
}
else if (strncasecmp (start, "\\Draft", end - start) == 0)
{
if (msg_imap)
msg_imap->flags |= MU_ATTRIBUTE_DRAFT;
else
f_imap->flags |= MU_ATTRIBUTE_DRAFT;
}
{
flags |= MU_ATTRIBUTE_DRAFT;
}
}
while (**ptr && **ptr != ')');
while (**ptr && **ptr != ')'); /* do {} */
/* Skip the last rparen. */
if (**ptr == ')')
(*ptr)++;
if (pflags)
*pflags = flags;
return 0;
}
......@@ -1548,7 +1552,7 @@ imap_fetch (f_imap_t f_imap)
if (strncmp (token, "FLAGS", 5) == 0)
{
status = imap_flags (f_imap, &sp);
status = imap_fetch_flags (f_imap, &sp);
}
else if (strcasecmp (token, "BODY") == 0)
{
......@@ -2053,7 +2057,7 @@ imap_parse (f_imap_t f_imap)
else if (strcasecmp (response, "FLAGS") == 0)
{
/* Flags define on the mailbox not a message flags. */
status = imap_flags (f_imap, &remainder);
status = imap_permanentflags (f_imap, &remainder);
}
else if (strcasecmp (response, "LIST") == 0)
{
......
......@@ -63,7 +63,8 @@ extern int mbox_get_size __P ((mbox_t, off_t *));
extern int mbox_get_separator __P ((mbox_t, unsigned int, char **));
extern int mbox_set_separator __P ((mbox_t, unsigned int, const char *));
extern int mbox_expunge __P ((mbox_t, int));
extern int mbox_expunge __P ((mbox_t));
extern int mbox_save __P ((mbox_t));
extern int mbox_has_newmail __P ((mbox_t));
extern int mbox_set_progress_cb __P ((mbox_t,
......@@ -73,8 +74,8 @@ extern int mbox_set_newmsg_cb __P ((mbox_t,
extern int mbox_set_error_cb __P ((mbox_t,
int (*) __P ((int, void *)), void *));
extern int mbox_scan __P ((mbox_t, unsigned int,
unsigned int *, int));
extern int mbox_scan __P ((mbox_t, unsigned int, unsigned int *));
extern int mbox_count __P ((mbox_t, unsigned int *));
extern int mbox_append __P ((mbox_t, const char *, attribute_t,
stream_t));
......
......@@ -36,6 +36,9 @@ extern "C" {
struct _pop3;
typedef struct _pop3* pop3_t;
typedef iterator_t pop3_capa_iterator_t;
typedef iterator_t pop3_list_iterator_t;
typedef iterator_t pop3_uidl_iterator_t;
extern int pop3_create __P ((pop3_t *));
extern void pop3_destroy __P ((pop3_t *));
......@@ -55,13 +58,22 @@ extern int pop3_get_debug __P ((pop3_t, mu_debug_t *));
extern int pop3_apop __P ((pop3_t, const char *, const char *));
extern int pop3_capa __P ((pop3_t, iterator_t *));
extern int pop3_capa_current __P ((iterator_t, char **));
extern int pop3_capa_first __P ((pop3_capa_iterator_t));
extern int pop3_capa_current __P ((pop3_capa_iterator_t, char **));
extern int pop3_capa_next __P ((pop3_capa_iterator_t));
extern int pop3_capa_is_done __P ((pop3_capa_iterator_t));
extern void pop3_capa_destroy __P ((pop3_capa_iterator_t *));
extern int pop3_dele __P ((pop3_t, unsigned int));
extern int pop3_list __P ((pop3_t, unsigned int, size_t *));
extern int pop3_list_all __P ((pop3_t, iterator_t *));
extern int pop3_list_current __P ((iterator_t, unsigned int *, size_t *));
extern int pop3_list_all __P ((pop3_t, pop3_list_iterator_t *));
extern int pop3_list_first __P ((pop3_list_iterator_t));
extern int pop3_list_current __P ((pop3_list_iterator_t,
unsigned int *, size_t *));
extern int pop3_list_next __P ((pop3_list_iterator_t));
extern int pop3_list_is_done __P ((pop3_list_iterator_t));
extern void pop3_list_destroy __P ((pop3_list_iterator_t *));
extern int pop3_noop __P ((pop3_t));
extern int pop3_pass __P ((pop3_t, const char *));
......@@ -73,8 +85,13 @@ extern int pop3_top __P ((pop3_t, unsigned int,
unsigned int, stream_t *));
extern int pop3_uidl __P ((pop3_t, unsigned int, char **));
extern int pop3_uidl_all __P ((pop3_t, iterator_t *));
extern int pop3_uidl_current __P ((iterator_t, unsigned int *, char **));
extern int pop3_uidl_all __P ((pop3_t, pop3_uidl_iterator_t *));
extern int pop3_uidl_first __P ((pop3_uidl_iterator_t));
extern int pop3_uidl_is_done __P ((pop3_uidl_iterator_t));
extern int pop3_uidl_current __P ((pop3_uidl_iterator_t,
unsigned int *, char **));
extern int pop3_uidl_next __P ((pop3_uidl_iterator_t));
extern void pop3_uidl_destroy __P ((pop3_uidl_iterator_t *));
extern int pop3_user __P ((pop3_t, const char *));
......
......@@ -128,11 +128,11 @@ extern int mbox_set_default_hcache __P ((mbox_t));
extern int mbox_debug_print __P ((mbox_t, const char *, ...));
extern int stream_mbox_create __P ((stream_t *, mbox_t, unsigned int, int));
extern int stream_mbox_msgno __P ((stream_t, unsigned int));
extern void _stream_mbox_dtor __P ((stream_t));
extern int stream_mbox_set_msgno __P ((stream_t, unsigned int));
extern void _stream_mbox_dtor __P ((stream_t));
extern int attribute_mbox_create __P ((attribute_t *, mbox_t, unsigned int));
extern int attribute_mbox_msgno __P ((attribute_t, unsigned int));
extern int attribute_mbox_set_msgno __P ((attribute_t, unsigned int));
extern int mbox_attribute_to_status __P ((attribute_t, char *, size_t,
size_t *));
extern void _attribute_mbox_dtor __P ((attribute_t));
......@@ -143,6 +143,8 @@ extern void mbox_release_hstream __P ((mbox_t, unsigned int));
extern void mbox_release_bstream __P ((mbox_t, unsigned int));
extern void mbox_release_msg __P ((mbox_t, unsigned int));
extern int mbox_scan0 __P ((mbox_t, unsigned int, unsigned int *, int));
#ifdef __cplusplus
}
#endif
......
......@@ -217,7 +217,7 @@ attribute_mbox_create (attribute_t *pattribute, mbox_t mbox,
}
int
attribute_mbox_msgno (attribute_t attribute, unsigned int msgno)
attribute_mbox_set_msgno (attribute_t attribute, unsigned int msgno)
{
struct _attribute_mbox *ma = (struct _attribute_mbox *)attribute;
if (ma)
......
......@@ -113,8 +113,8 @@ mbox_tmpfile (mbox_t mbox, char **pbox)
The real downside to the approach is that when things go wrong
the temporary file may be left in /tmp, which is not all that bad
because at least, we have something to recuperate when failure. */
int
mbox_expunge (mbox_t mbox, int remove_deleted)
static int
mbox_expunge0 (mbox_t mbox, int remove_deleted)
{
mbox_message_t mum;
int status = 0;
......@@ -382,9 +382,9 @@ mbox_expunge (mbox_t mbox, int remove_deleted)
mum->from_ = mum->header.start = 0;
mum->body.start = mum->body.end = 0;
mum->header.lines = mum->body.lines = 0;
stream_mbox_msgno (mum->header.stream, j + 1);
stream_mbox_msgno (mum->body.stream, j + 1);
attribute_mbox_msgno (mum->attribute, j + 1);
stream_mbox_set_msgno (mum->header.stream, j + 1);
stream_mbox_set_msgno (mum->body.stream, j + 1);
attribute_mbox_set_msgno (mum->attribute, j + 1);
}
}
......@@ -396,7 +396,19 @@ mbox_expunge (mbox_t mbox, int remove_deleted)
/* This should reset the messages_count, the last argument 0 means
not to send event notification. */
mbox_scan (mbox, dirty, NULL, 0);
mbox_scan0 (mbox, dirty, NULL, 0);
}
return status;
}
int
mbox_expunge (mbox_t mbox)
{
return mbox_expunge0 (mbox, 1);
}
int
mbox_save (mbox_t mbox)
{
return mbox_expunge0 (mbox, 0);
}
......
......@@ -134,9 +134,9 @@ mbox_alloc_umessages (mbox_t mbox)
The approach is to detect the "From " at the start of a new message, give
the position of the header and scan until "\n" then set header and body
position, scan until we it another "From ". */
int
mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif)
mbox_scan0 (mbox_t mbox, unsigned int msgno, unsigned int *pcount,
int do_notif)
{
#define MSGLINELEN 1024
char buf[MSGLINELEN];
......@@ -418,3 +418,15 @@ mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount, int do_notif)
lockfile_unlock (mbox->lockfile);
return status;
}
int
mbox_scan (mbox_t mbox, unsigned int msgno, unsigned int *pcount)
{
return mbox_scan0 (mbox, msgno, pcount, 1);
}
int
mbox_count (mbox_t mbox, unsigned int *pcount)
{
return mbox_scan0 (mbox, 1, pcount, 0);
}
......
......@@ -97,6 +97,6 @@ mbox_set_separator (mbox_t mbox, unsigned int msgno, const char *sep)
if (mbox->umessages[msgno]->separator)
free (mbox->umessages[msgno]->separator);
mbox->umessages[msgno]->separator = (sep) ? strdup (sep) : NULL;
mbox->umessage[msgno]->attr_flags |= MU_ATTRIBUTE_MODIFIED;
mbox->umessages[msgno]->attr_flags |= MU_ATTRIBUTE_MODIFIED;
return 0;
}
......
......@@ -368,7 +368,7 @@ _stream_mbox_dtor (stream_t stream)
}
int
stream_mbox_msgno (stream_t stream, unsigned int msgno)
stream_mbox_set_msgno (stream_t stream, unsigned int msgno)
{
struct _stream_mbox *ms = (struct _stream_mbox *)stream;
if (ms)
......
......@@ -35,7 +35,7 @@ mbox_get_uidnext (mbox_t mbox, unsigned long *puidnext)
the mailbox as change on disk. */
if (mbox->messages_count == 0)
{
int status = mbox_scan (mbox, 0, NULL, 0);
int status = mbox_count (mbox, NULL);
if (status != 0)
return status;
}
......
......@@ -34,7 +34,7 @@ mbox_get_uidvalidity (mbox_t mbox, unsigned long *puidvalidity)
/* If we did not start a scanning yet do it now. */
if (mbox->messages_count == 0)
{
int status = mbox_scan (mbox, 0, NULL, 0);
int status = mbox_count (mbox, NULL);
if (status != 0)
return status;
}
......
......@@ -69,3 +69,33 @@ pop3_capa (pop3_t pop3, iterator_t *piterator)
return status;
}
int
pop3_capa_first (pop3_capa_iterator_t iterator)
{
return iterator_first (iterator);
}
int
pop3_capa_current (pop3_capa_iterator_t iterator, char **s)
{
return iterator_current (iterator, s);
}
int
pop3_capa_next (pop3_capa_iterator_t iterator)
{
return iterator_next (iterator);
}
int
pop3_capa_is_done (pop3_capa_iterator_t iterator)
{
return iterator_is_done (iterator);
}
void
pop3_capa_destroy (pop3_capa_iterator_t *piterator)
{
iterator_destroy (piterator);
}
......
......@@ -76,7 +76,32 @@ pop3_list_all (pop3_t pop3, iterator_t *piterator)
}
int
pop3_list_current (iterator_t iterator, unsigned int *pno, size_t *plen)
pop3_list_first (pop3_list_iterator_t iterator)
{
return iterator_first (iterator);
}
int
pop3_list_next (pop3_list_iterator_t iterator)
{
return iterator_next (iterator);
}
int
pop3_list_is_done (pop3_list_iterator_t iterator)
{
return iterator_is_done (iterator);
}
void
pop3_list_destroy (pop3_list_iterator_t *piterator)
{
iterator_destroy (piterator);
}
int
pop3_list_current (pop3_list_iterator_t iterator, unsigned int *pno,
size_t *plen)
{
char *buf;
int status = iterator_current (iterator, (void *)&buf);
......
......@@ -75,6 +75,30 @@ pop3_uidl_all (pop3_t pop3, iterator_t *piterator)
}
int
pop3_uidl_first (pop3_uidl_iterator_t iterator)
{
return iterator_first (iterator);
}
int
pop3_uidl_is_done (pop3_uidl_iterator_t iterator)
{
return iterator_is_done (iterator);
}
int
pop3_uidl_next (pop3_uidl_iterator_t iterator)
{
return iterator_next (iterator);
}
void
pop3_uidl_destroy (pop3_uidl_iterator_t *piterator)
{
iterator_destroy (piterator);
}
int
pop3_uidl_current (iterator_t iterator, unsigned int *pno, char **puidl)
{
char *buf;
......