Commit 927c27f8 927c27f8e4bc2c8ae5699addfbcd833d8fec6e08 by Sergey Poznyakoff

Fix input operations and RFC-compliance in imap4d.

* imap4d/util.c (util_getword, util_getitem, util_token)
(util_unquote): Remove.
(imap4d_readline): Rewrite to reduce memory reallocation.  Add
support for non-synchronizing literals (RFC 2088).
(imap4d_readline_ex): Remove.
(util_do_command): Rewrite using new imap4d_readline.
(util_parse_internal_date0): Remove.
(imap4d_tokbuf_init, imap4d_tokbuf_destroy, imap4d_tokbuf_argc)
(imap4d_tokbuf_getarg, util_isdelim)
(imap4d_tokbuf_from_string): New functions.
* imap4d/append.c, imap4d/auth_gss.c, imap4d/authenticate.c,
imap4d/check.c, imap4d/close.c, imap4d/commands.c, imap4d/copy.c,
imap4d/create.c, imap4d/delete.c, imap4d/examine.c,
imap4d/imap4d.h, imap4d/list.c, imap4d/login.c, imap4d/logout.c,
imap4d/lsub.c, imap4d/expunge.c, imap4d/idle.c, imap4d/noop.c,
imap4d/rename.c, imap4d/search.c, imap4d/select.c,
imap4d/starttls.c, imap4d/status.c, imap4d/store.c,
imap4d/subscribe.c, imap4d/uid.c, imap4d/unsubscribe.c,
imap4d/version.c: Rewrite using new imap4d_readline.
* imap4d/namespace.c: Use new imap4d_readline.  Ensure that
each reported prefix ends with a hierarchy delimiter.
* imap4d/imap4d.c (imap4d_mainloop): Use new imap4d_readline.
* imap4d/fetch.c: Rewrite parser from scratch.
* imap4d/capability.c (imap4d_capability_init): Report LITERAL+
capability.

* imap4d/testsuite/imap4d/anystate.exp: Account for the LITERAL+
capability.
* imap4d/testsuite/imap4d/append.exp: Fix APPEND arguments (imap4d
requires exactly three arguments, as per RFC3501.
Fix octet count in literals returned by fetch (previous versions
failed to include the trailing CRLF).
* imap4d/testsuite/imap4d/create.exp: Likewise.
* imap4d/testsuite/imap4d/fetch.exp: Fix FETCH arguments (previous
versions incorrectly accepted header-list without parentheses.
Fix result of FETCH 4 BODY[2.2.1]: it returns entire part, in the
contrast to previous versions, which treated it as
BODY[2.2.1.TEXT].

* maidag/mailtmp.c (mail_tmp_finish): Ensure /dev/null is treated
as mailbox.
1 parent 7317a04a
2008-08-11 Sergey Poznyakoff <gray@gnu.org.ua>
Fix input operations and RFC-compliance in imap4d.
* imap4d/util.c (util_getword, util_getitem, util_token)
(util_unquote): Remove.
(imap4d_readline): Rewrite to reduce memory reallocation. Add
support for non-synchronizing literals (RFC 2088).
(imap4d_readline_ex): Remove.
(util_do_command): Rewrite using new imap4d_readline.
(util_parse_internal_date0): Remove.
(imap4d_tokbuf_init, imap4d_tokbuf_destroy, imap4d_tokbuf_argc)
(imap4d_tokbuf_getarg, util_isdelim)
(imap4d_tokbuf_from_string): New functions.
* imap4d/append.c, imap4d/auth_gss.c, imap4d/authenticate.c,
imap4d/check.c, imap4d/close.c, imap4d/commands.c, imap4d/copy.c,
imap4d/create.c, imap4d/delete.c, imap4d/examine.c,
imap4d/imap4d.h, imap4d/list.c, imap4d/login.c, imap4d/logout.c,
imap4d/lsub.c, imap4d/expunge.c, imap4d/idle.c, imap4d/noop.c,
imap4d/rename.c, imap4d/search.c, imap4d/select.c,
imap4d/starttls.c, imap4d/status.c, imap4d/store.c,
imap4d/subscribe.c, imap4d/uid.c, imap4d/unsubscribe.c,
imap4d/version.c: Rewrite using new imap4d_readline.
* imap4d/namespace.c: Use new imap4d_readline. Ensure that
each reported prefix ends with a hierarchy delimiter.
* imap4d/imap4d.c (imap4d_mainloop): Use new imap4d_readline.
* imap4d/fetch.c: Rewrite parser from scratch.
* imap4d/capability.c (imap4d_capability_init): Report LITERAL+
capability.
* imap4d/testsuite/imap4d/anystate.exp: Account for the LITERAL+
capability.
* imap4d/testsuite/imap4d/append.exp: Fix APPEND arguments (imap4d
requires exactly three arguments, as per RFC3501.
Fix octet count in literals returned by fetch (previous versions
failed to include the trailing CRLF).
* imap4d/testsuite/imap4d/create.exp: Likewise.
* imap4d/testsuite/imap4d/fetch.exp: Fix FETCH arguments (previous
versions incorrectly accepted header-list without parentheses.
Fix result of FETCH 4 BODY[2.2.1]: it returns entire part, in the
contrast to previous versions, which treated it as
BODY[2.2.1.TEXT].
* maidag/mailtmp.c (mail_tmp_finish): Ensure /dev/null is treated
as mailbox.
2008-08-08 Sergey Poznyakoff <gray@gnu.org.ua>
Fix imap appends for AMD mailboxes.
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2006, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2006, 2007,
2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -18,49 +19,6 @@
#include "imap4d.h"
/* APPEND mbox [(flags)] [date_time] message_literal */
int
imap4d_append (struct imap4d_command *command, char *arg)
{
char *sp;
char *mboxname;
int flags = 0;
mu_mailbox_t dest_mbox = NULL;
int status;
mboxname = util_getword (arg, &sp);
if (!mboxname)
return util_finish (command, RESP_BAD, "Too few arguments");
util_unquote (&mboxname);
if (*sp == '(' && util_parse_attributes (sp+1, &sp, &flags))
return util_finish (command, RESP_BAD, "Missing closing parenthesis");
mboxname = namespace_getfullpath (mboxname, "/");
if (!mboxname)
return util_finish (command, RESP_NO, "Couldn't open mailbox");
status = mu_mailbox_create_default (&dest_mbox, mboxname);
if (status == 0)
{
/* It SHOULD NOT automatifcllly create the mailbox. */
status = mu_mailbox_open (dest_mbox, MU_STREAM_RDWR);
if (status == 0)
{
status = imap4d_append0 (dest_mbox, flags, sp);
mu_mailbox_close (dest_mbox);
}
mu_mailbox_destroy (&dest_mbox);
}
free (mboxname);
if (status == 0)
return util_finish (command, RESP_OK, "Completed");
return util_finish (command, RESP_NO, "[TRYCREATE] failed");
}
static int
_append_date (mu_envelope_t envelope, char *buf, size_t len, size_t *pnwrite)
{
......@@ -93,12 +51,18 @@ _append_size (mu_message_t msg, size_t *psize)
mu_stream_t str;
int status = mu_message_get_stream (msg, &str);
if (status == 0)
status = mu_stream_size (str, psize);
{
mu_off_t size;
status = mu_stream_size (str, &size);
if (status == 0 && psize)
*psize = size;
}
return status;
}
int
imap4d_append0 (mu_mailbox_t mbox, int flags, char *text)
imap4d_append0 (mu_mailbox_t mbox, int flags, char *date_time, char *text,
char **err_text)
{
mu_stream_t stream;
int rc = 0;
......@@ -118,23 +82,25 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char *text)
return 1;
}
while (*text && isspace (*text))
text++;
/* If a date_time is specified, the internal date SHOULD be set in the
resulting message; otherwise, the internal date of the resulting
message is set to the current date and time by default. */
if (util_parse_internal_date0 (text, &t, &text) == 0)
if (date_time)
{
while (*text && isspace(*text))
text++;
if (util_parse_internal_date (date_time, &t))
{
*err_text = "Invalid date/time format";
return 1;
}
}
else
{
time(&t);
}
tm = gmtime(&t);
while (*text && isspace (*text))
text++;
mu_stream_write (stream, text, strlen (text), len, &len);
mu_message_set_stream (msg, stream, &tm);
mu_message_set_size (msg, _append_size, &tm);
......@@ -159,3 +125,86 @@ imap4d_append0 (mu_mailbox_t mbox, int flags, char *text)
}
/* APPEND mbox [(flags)] [date_time] message_literal */
int
imap4d_append (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int i;
char *mboxname;
int flags = 0;
mu_mailbox_t dest_mbox = NULL;
int status;
int argc = imap4d_tokbuf_argc (tok);
char *date_time;
char *msg_text;
char *err_text = "[TRYCREATE] failed";
if (argc < 4)
return util_finish (command, RESP_BAD, "Too few arguments");
mboxname = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
if (!mboxname)
return util_finish (command, RESP_BAD, "Too few arguments");
i = IMAP4_ARG_2;
if (imap4d_tokbuf_getarg (tok, i)[0] == '(')
{
while (++i < argc)
{
int type;
char *arg = imap4d_tokbuf_getarg (tok, i);
if (!util_attribute_to_type (arg, &type))
flags |= type;
else if (arg[0] == ')')
break;
}
if (i == argc)
return util_finish (command, RESP_BAD, "Missing closing parenthesis");
i++;
}
switch (argc - i)
{
case 2:
/* Date/time is present */
date_time = imap4d_tokbuf_getarg (tok, i);
i++;
break;
case 1:
date_time = NULL;
break;
default:
return util_finish (command, RESP_BAD, "Too many arguments");
}
msg_text = imap4d_tokbuf_getarg (tok, i);
mboxname = namespace_getfullpath (mboxname, "/");
if (!mboxname)
return util_finish (command, RESP_NO, "Couldn't open mailbox");
status = mu_mailbox_create_default (&dest_mbox, mboxname);
if (status == 0)
{
/* It SHOULD NOT automatically create the mailbox. */
status = mu_mailbox_open (dest_mbox, MU_STREAM_RDWR);
if (status == 0)
{
status = imap4d_append0 (dest_mbox, flags, date_time, msg_text,
&err_text);
mu_mailbox_close (dest_mbox);
}
mu_mailbox_destroy (&dest_mbox);
}
free (mboxname);
if (status == 0)
return util_finish (command, RESP_OK, "Completed");
return util_finish (command, RESP_NO, err_text);
}
......
......@@ -119,7 +119,9 @@ auth_gssapi (struct imap4d_command *command,
gss_ctx_id_t context;
gss_cred_id_t cred_handle, server_creds;
gss_OID mech_type;
char *token_str;
char *token_str = NULL;
size_t token_size = 0;
size_t token_len;
unsigned char *tmp = NULL;
size_t size;
gss_name_t server_name;
......@@ -168,11 +170,10 @@ auth_gssapi (struct imap4d_command *command,
for (;;)
{
token_str = imap4d_readline_ex ();
util_base64_decode (token_str, strlen (token_str), &tmp, &size);
imap4d_getline (&token_str, &token_size, &token_len);
util_base64_decode (token_str, token_len, &tmp, &size);
tokbuf.value = tmp;
tokbuf.length = size;
free (token_str);
maj_stat = gss_accept_sec_context (&min_stat,
&context,
......@@ -202,6 +203,7 @@ auth_gssapi (struct imap4d_command *command,
display_status ("accept context", maj_stat, min_stat);
maj_stat = gss_delete_sec_context (&min_stat, &context, &outbuf);
gss_release_buffer (&min_stat, &outbuf);
free (token_str);
return RESP_NO;
}
......@@ -211,8 +213,7 @@ auth_gssapi (struct imap4d_command *command,
util_send ("+ %*.*s\r\n", size, size, tmp);
free (tmp);
gss_release_buffer (&min_stat, &outbuf);
token_str = imap4d_readline_ex ();
free (token_str);
imap4d_getline (&token_str, &token_size, &token_len);
}
/* Construct security-level data */
......@@ -224,6 +225,7 @@ auth_gssapi (struct imap4d_command *command,
if (maj_stat != GSS_S_COMPLETE)
{
display_status ("wrap", maj_stat, min_stat);
free (token_str);
return RESP_NO;
}
......@@ -231,8 +233,8 @@ auth_gssapi (struct imap4d_command *command,
util_send ("+ %*.*s\r\n", size, size, tmp);
free (tmp);
token_str = imap4d_readline_ex ();
util_base64_decode (token_str, strlen (token_str),
imap4d_getline (&token_str, &token_size, &token_len);
util_base64_decode (token_str, token_len,
(unsigned char **) &tokbuf.value, &tokbuf.length);
free (token_str);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2006, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2006, 2007,
2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -93,24 +94,30 @@ imap4d_auth_capability ()
mu_list_do (imap_auth_list, _auth_capa, NULL);
}
/*
6.2.1. AUTHENTICATE Command
Arguments: authentication mechanism name
*/
int
imap4d_authenticate (struct imap4d_command *command, char *arg)
imap4d_authenticate (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
char *auth_type;
struct auth_data adata;
auth_type = util_getword (arg, &sp);
util_unquote (&auth_type);
if (!auth_type)
return util_finish (command, RESP_BAD, "Too few arguments");
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
auth_type = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
if (tls_required)
return util_finish (command, RESP_NO, "Command disabled: Use STARTTLS first");
return util_finish (command, RESP_NO,
"Command disabled: Use STARTTLS first");
adata.command = command;
adata.auth_type = auth_type;
adata.arg = sp;
adata.arg = NULL;
adata.username = NULL;
if (mu_list_do (imap_auth_list, _auth_try, &adata) == 0)
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2003, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2003, 2005, 2007,
2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -50,6 +51,7 @@ imap4d_capability_init ()
"IMAP4rev1",
"NAMESPACE",
"IDLE",
"LITERAL+",
"X-VERSION",
NULL
};
......@@ -67,8 +69,11 @@ print_capa (void *item, void *data)
}
int
imap4d_capability (struct imap4d_command *command, char *arg MU_ARG_UNUSED)
imap4d_capability (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
util_send ("* CAPABILITY");
mu_list_do (capa_list, print_capa, NULL);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,13 +19,20 @@
#include "imap4d.h"
/*
* Do we need to do anything here?
* FIXME: This is like noop we need to notify the client of
* new mails etc ... and do housekeeping.
*/
6.4.1. CHECK Command
Arguments: none
Responses: no specific responses for this command
Result: OK - check completed
BAD - command unknown or arguments invalid
*/
int
imap4d_check (struct imap4d_command *command, char *arg MU_ARG_UNUSED)
imap4d_check (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2004, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2004, 2005, 2007,
2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,17 +20,28 @@
#include "imap4d.h"
/*
*/
6.4.2. CLOSE Command
/* The CLOSE command permanently removes from the currently selected
Arguments: none
Responses: no specific responses for this command
Result: OK - close completed, now in authenticated state
NO - close failure: no mailbox selected
BAD - command unknown or arguments invalid
The CLOSE command permanently removes from the currently selected
mailbox all messages that have the \\Deleted flag set, and returns
to authenticated state from selected state. */
int
imap4d_close (struct imap4d_command *command, char *arg MU_ARG_UNUSED)
imap4d_close (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
const char *msg = NULL;
int status, flags;
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
mu_mailbox_get_flags (mbox, &flags);
if ((flags & MU_STREAM_READ) == 0)
{
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2003, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2003, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,55 +19,69 @@
#include "imap4d.h"
/*
* copy messages in argv[2] to mailbox in argv[3]
6.4.7. COPY Command
Arguments: message set
mailbox name
Responses: no specific responses for this command
Result: OK - copy completed
NO - copy error: can't copy those messages or to that
name
BAD - command unknown or arguments invalid
copy messages in argv[2] to mailbox in argv[3]
*/
int
imap4d_copy (struct imap4d_command *command, char *arg)
imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int rc;
char buffer[64];
char *text;
if (imap4d_tokbuf_argc (tok) != 4)
return util_finish (command, RESP_BAD, "Invalid arguments");
rc = imap4d_copy0 (tok, 0, &text);
rc = imap4d_copy0 (arg, 0, buffer, sizeof buffer);
if (rc == RESP_NONE)
{
/* Reset the state ourself. */
int new_state = (rc == RESP_OK) ? command->success : command->failure;
if (new_state != STATE_NONE)
state = new_state;
return util_send ("%s %s\r\n", command->tag, buffer);
return util_send ("%s %s\r\n", command->tag, text);
}
return util_finish (command, rc, "%s", buffer);
return util_finish (command, rc, "%s", text);
}
int
imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen)
imap4d_copy0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
{
int status;
char *msgset;
char *name;
char *mailbox_name;
const char *delim = "/";
char *sp = NULL;
size_t *set = NULL;
int n = 0;
mu_mailbox_t cmbox = NULL;
int arg = IMAP4_ARG_1 + !!isuid;
msgset = util_getword (arg, &sp);
name = util_getword (NULL, &sp);
util_unquote (&name);
if (!msgset || !name || *name == '\0')
if (imap4d_tokbuf_argc (tok) != arg + 2)
{
snprintf (resp, resplen, "Too few args");
return RESP_BAD;
*err_text = "Invalid arguments";
return 1;
}
msgset = imap4d_tokbuf_getarg (tok, arg);
name = imap4d_tokbuf_getarg (tok, arg + 1);
/* Get the message numbers in set[]. */
status = util_msgset (msgset, &set, &n, isuid);
if (status != 0)
{
snprintf (resp, resplen, "Bogus number set");
*err_text = "Bogus number set";
return RESP_BAD;
}
......@@ -75,7 +89,7 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen)
if (!mailbox_name)
{
snprintf (resp, resplen, "NO Create failed.");
*err_text = "NO Create failed.";
return RESP_NO;
}
......@@ -105,7 +119,7 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen)
if (status == 0)
{
snprintf (resp, resplen, "Completed");
*err_text = "Completed";
return RESP_OK;
}
......@@ -114,6 +128,6 @@ imap4d_copy0 (char *arg, int isuid, char *resp, size_t resplen)
of the text of the tagged NO response. This gives a hint to the
client that it can attempt a CREATE command and retry the copy if
the CREATE is successful. */
snprintf (resp, resplen, "NO [TRYCREATE] failed");
*err_text = "NO [TRYCREATE] failed";
return RESP_NONE;
}
......
......@@ -63,25 +63,34 @@ mkdir_p (char *name, int delim)
return 0;
}
/*
6.3.3. CREATE Command
Arguments: mailbox name
Responses: no specific responses for this command
Result: OK - create completed
NO - create failure: can't create mailbox with that name
BAD - command unknown or arguments invalid
*/
/* FIXME: How do we do this ??????:
IF a new mailbox is created with the same name as a mailbox which was
deleted, its unique identifiers MUST be greater than any unique identifiers
used in the previous incarnation of the mailbox. */
int
imap4d_create (struct imap4d_command *command, char *arg)
imap4d_create (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *name;
char *sp = NULL;
const char *delim = "/";
int isdir = 0;
int rc = RESP_OK;
const char *msg = "Completed";
name = util_getword (arg, &sp);
if (!name)
return util_finish (command, RESP_BAD, "Too few arguments");
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
util_unquote (&name);
name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
if (*name == '\0')
return util_finish (command, RESP_BAD, "Too few arguments");
......@@ -152,6 +161,5 @@ imap4d_create (struct imap4d_command *command, char *arg)
msg = "already exists";
}
free (name);
return util_finish (command, rc, msg);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,20 +19,27 @@
#include "imap4d.h"
/*
*
*/
6.3.4. DELETE Command
Arguments: mailbox name
Responses: no specific responses for this command
Result: OK - delete completed
NO - delete failure: can't delete mailbox with that name
BAD - command unknown or arguments invalid
*/
int
imap4d_delete (struct imap4d_command *command, char *arg)
imap4d_delete (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
int rc = RESP_OK;
const char *msg = "Completed";
const char *delim = "/";
char *name;
name = util_getword (arg, &sp);
util_unquote (&name);
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
if (!name || *name == '\0')
return util_finish (command, RESP_BAD, "Too few arguments");
......@@ -51,6 +58,5 @@ imap4d_delete (struct imap4d_command *command, char *arg)
rc = RESP_NO;
msg = "Cannot remove";
}
free (name);
return util_finish (command, rc, msg);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,11 +19,23 @@
#include "imap4d.h"
/*
* copy things from select.c
*/
6.3.2. EXAMINE Command
Arguments: mailbox name
Responses: REQUIRED untagged responses: FLAGS, EXISTS, RECENT
OPTIONAL OK untagged responses: UNSEEN, PERMANENTFLAGS
Result: OK - examine completed, now in selected state
NO - examine failure, now in authenticated state: no
such mailbox, can't access mailbox
BAD - command unknown or arguments invalid
*/
int
imap4d_examine (struct imap4d_command *command, char *arg)
imap4d_examine (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
return imap4d_select0 (command, arg, MU_STREAM_READ);
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
return imap4d_select0 (command, imap4d_tokbuf_getarg (tok, IMAP4_ARG_1),
MU_STREAM_READ);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,16 +19,23 @@
#include "imap4d.h"
/*
*
*/
6.4.3. EXPUNGE Command
Arguments: none
Responses: untagged responses: EXPUNGE
Result: OK - expunge completed
NO - expunge failure: can't expunge (e.g. permission
denied)
BAD - command unknown or arguments invalid
*/
int
imap4d_expunge (struct imap4d_command *command, char *arg)
imap4d_expunge (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
if (util_getword (arg, &sp))
return util_finish (command, RESP_NO, "Too many args");
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
/* FIXME: check for errors. */
mu_mailbox_expunge (mbox);
......
......@@ -19,13 +19,12 @@
#include "imap4d.h"
int
imap4d_idle (struct imap4d_command *command, char *arg)
imap4d_idle (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp;
time_t start;
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
if (util_wait_input (0) == -1)
return util_finish (command, RESP_NO, "Cannot idle");
......@@ -38,15 +37,10 @@ imap4d_idle (struct imap4d_command *command, char *arg)
{
if (util_wait_input (5))
{
int rc;
char *p;
char *cmd = imap4d_readline ();
p = util_getword (cmd, &sp);
rc = strcasecmp (p, "done") == 0;
free (cmd);
if (rc)
imap4d_readline (tok);
if (imap4d_tokbuf_argc (tok) == 1
&& strcasecmp (imap4d_tokbuf_getarg (tok, IMAP4_ARG_TAG),
"done") == 0)
break;
}
else if (time (NULL) - start > idle_timeout)
......
......@@ -370,6 +370,7 @@ get_client_address (int fd, struct sockaddr_in *pcs)
static int
imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
{
imap4d_tokbuf_t tokp;
char *text;
int debug_mode = isatty (fd);
static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
......@@ -400,14 +401,14 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
util_out ((state == STATE_AUTH) ? RESP_PREAUTH : RESP_OK, "%s", text);
util_flush_output ();
tokp = imap4d_tokbuf_init ();
while (1)
{
char *cmd = imap4d_readline ();
imap4d_readline (tokp);
/* check for updates */
imap4d_sync ();
util_do_command (cmd);
util_do_command (tokp);
imap4d_sync ();
free (cmd);
util_flush_output ();
}
......
......@@ -41,6 +41,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <setjmp.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <syslog.h>
......@@ -108,10 +109,12 @@
extern "C" {
#endif
typedef struct imap4d_tokbuf *imap4d_tokbuf_t;
struct imap4d_command
{
const char *name;
int (*func) (struct imap4d_command *, char *);
int (*func) (struct imap4d_command *, imap4d_tokbuf_t);
int states;
int failure;
int success;
......@@ -192,47 +195,62 @@ extern int imap4d_transcript;
extern char *strtok_r (char *s, const char *delim, char **save_ptr);
#endif
/* Imap4 commands */
extern int imap4d_append (struct imap4d_command *, char *);
extern int imap4d_append0 (mu_mailbox_t mbox, int flags, char *text);
extern int imap4d_authenticate (struct imap4d_command *, char *);
/* Input functions */
imap4d_tokbuf_t imap4d_tokbuf_init (void);
void imap4d_tokbuf_destroy (imap4d_tokbuf_t *tok);
int imap4d_tokbuf_argc (imap4d_tokbuf_t tok);
char *imap4d_tokbuf_getarg (imap4d_tokbuf_t tok, int n);
void imap4d_readline (imap4d_tokbuf_t tok);
struct imap4d_tokbuf *imap4d_tokbuf_from_string (char *str);
int imap4d_getline (char **pbuf, size_t *psize, size_t *pnbytes);
#define IMAP4_ARG_TAG 0
#define IMAP4_ARG_COMMAND 1
#define IMAP4_ARG_1 2
#define IMAP4_ARG_2 3
#define IMAP4_ARG_3 4
#define IMAP4_ARG_4 5
/* Imap4 commands */
extern int imap4d_append (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_authenticate (struct imap4d_command *, imap4d_tokbuf_t);
extern void imap4d_auth_capability (void);
extern int imap4d_capability (struct imap4d_command *, char *);
extern int imap4d_check (struct imap4d_command *, char *);
extern int imap4d_close (struct imap4d_command *, char *);
extern int imap4d_copy (struct imap4d_command *, char *);
extern int imap4d_copy0 (char *, int, char *, size_t);
extern int imap4d_create (struct imap4d_command *, char *);
extern int imap4d_delete (struct imap4d_command *, char *);
extern int imap4d_examine (struct imap4d_command *, char *);
extern int imap4d_expunge (struct imap4d_command *, char *);
extern int imap4d_fetch (struct imap4d_command *, char *);
extern int imap4d_fetch0 (char *, int, char *, size_t);
extern int imap4d_list (struct imap4d_command *, char *);
extern int imap4d_lsub (struct imap4d_command *, char *);
extern int imap4d_login (struct imap4d_command *, char *);
extern int imap4d_logout (struct imap4d_command *, char *);
extern int imap4d_noop (struct imap4d_command *, char *);
extern int imap4d_rename (struct imap4d_command *, char *);
extern int imap4d_capability (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_check (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_close (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_copy (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_copy0 (imap4d_tokbuf_t, int isuid, char **err_text);
extern int imap4d_create (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_delete (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_examine (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_expunge (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_fetch (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text);
extern int imap4d_list (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_lsub (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_login (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_logout (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_noop (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_rename (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_preauth_setup (int fd);
extern int imap4d_search (struct imap4d_command *, char *);
extern int imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize);
extern int imap4d_select (struct imap4d_command *, char *);
extern int imap4d_search (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_search0 (imap4d_tokbuf_t, int isuid, char **repyptr);
extern int imap4d_select (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_select0 (struct imap4d_command *, char *, int);
extern int imap4d_select_status (void);
#ifdef WITH_TLS
extern int imap4d_starttls (struct imap4d_command *, char *);
extern int imap4d_starttls (struct imap4d_command *, imap4d_tokbuf_t);
extern void starttls_init (void);
#endif /* WITH_TLS */
extern int imap4d_status (struct imap4d_command *, char *);
extern int imap4d_store (struct imap4d_command *, char *);
extern int imap4d_store0 (char *, int, char *, size_t);
extern int imap4d_subscribe (struct imap4d_command *, char *);
extern int imap4d_uid (struct imap4d_command *, char *);
extern int imap4d_unsubscribe (struct imap4d_command *, char *);
extern int imap4d_namespace (struct imap4d_command *, char *);
extern int imap4d_version (struct imap4d_command *, char *);
extern int imap4d_idle (struct imap4d_command *, char *);
extern int imap4d_status (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_store (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_store0 (imap4d_tokbuf_t, int, char **);
extern int imap4d_subscribe (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_uid (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_unsubscribe (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_namespace (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_version (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_idle (struct imap4d_command *, imap4d_tokbuf_t);
extern int imap4d_check_home_dir (const char *dir, uid_t uid, gid_t gid);
......@@ -274,25 +292,17 @@ extern int util_start (char *);
extern int util_finish (struct imap4d_command *, int, const char *, ...)
MU_PRINTFLIKE(3,4);
extern int util_getstate (void);
extern int util_do_command (char *);
extern char *imap4d_readline (void);
extern char *imap4d_readline_ex (void);
extern char *util_getword (char *, char **);
extern char *util_getitem (char *, const char *, char **);
extern int util_token (char *, size_t, char **);
extern void util_unquote (char **);
extern int util_do_command (imap4d_tokbuf_t);
extern char *util_tilde_expansion (const char *, const char *);
extern char *util_getfullpath (char *, const char *);
extern int util_msgset (char *, size_t **, int *, int);
extern int util_upper (char *);
extern struct imap4d_command *util_getcommand (char *,
struct imap4d_command []);
extern int util_parse_internal_date0 (char *date, time_t *timep, char **endp);
extern int util_parse_internal_date (char *date, time_t *timep);
extern int util_parse_822_date (const char *date, time_t *timep);
extern int util_parse_ctime_date (const char *date, time_t *timep);
extern char *util_strcasestr (const char *haystack, const char *needle);
extern int util_parse_attributes (char *items, char **save, int *flags);
extern int util_base64_encode (const unsigned char *input,
size_t input_len,
......@@ -330,6 +340,7 @@ void util_bye (void);
void util_atexit (void (*fp) (void));
void util_chdir (const char *homedir);
int is_atom (const char *s);
int util_isdelim (const char *str);
#ifdef WITH_TLS
int imap4d_init_tls_server (void);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2002, 2005, 2006,
2007 Free Software Foundation, Inc.
2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -106,6 +106,19 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data)
}
/*
6.3.8. LIST Command
Arguments: reference name
mailbox name with possible wildcards
Responses: untagged responses: LIST
Result: OK - list completed
NO - list failure: can't list that reference or name
BAD - command unknown or arguments invalid
*/
/*
1- IMAP4 insists: the reference argument present in the
interpreted form SHOULD prefix the interpreted form. It SHOULD
also be in the same form as the reference name argument. This
......@@ -126,21 +139,17 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data)
but it does not match the hierarchy delimiter. */
int
imap4d_list (struct imap4d_command *command, char *arg)
imap4d_list (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
char *ref;
char *wcard;
const char *delim = "/";
ref = util_getword (arg, &sp);
wcard = util_getword (NULL, &sp);
if (!ref || !wcard)
return util_finish (command, RESP_BAD, "Too few arguments");
if (imap4d_tokbuf_argc (tok) != 4)
return util_finish (command, RESP_BAD, "Invalid arguments");
/* Remove the double quotes. */
util_unquote (&ref);
util_unquote (&wcard);
ref = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
wcard = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2);
/* If wildcard is empty, it is a special case: we have to
return the hierarchy. */
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2002, 2006,
2007 Free Software Foundation, Inc.
2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,26 +19,32 @@
#include "imap4d.h"
/*
6.2.2. LOGIN Command
Arguments: user name
password
Responses: no specific responses for this command
Result: OK - login completed, now in authenticated state
NO - login failure: user name or password rejected
BAD - command unknown or arguments invalid
*/
int
imap4d_login (struct imap4d_command *command, char *arg)
imap4d_login (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL, *username, *pass;
char *username, *pass;
int rc;
if (login_disabled || tls_required)
return util_finish (command, RESP_NO, "Command disabled");
username = util_getword (arg, &sp);
pass = util_getword (NULL, &sp);
/* Remove the double quotes. */
util_unquote (&username);
util_unquote (&pass);
if (imap4d_tokbuf_argc (tok) != 4)
return util_finish (command, RESP_BAD, "Invalid arguments");
if (username == NULL || *username == '\0' || pass == NULL)
return util_finish (command, RESP_NO, "Too few args");
else if (util_getword (NULL, &sp))
return util_finish (command, RESP_NO, "Too many args");
username = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
pass = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2);
auth_data = mu_get_auth_by_name (username);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,15 +19,21 @@
#include "imap4d.h"
/*
* This needs to properly close the mailbox
*/
6.1.3. LOGOUT Command
Arguments: none
Responses: REQUIRED untagged response: BYE
Result: OK - logout completed
BAD - command unknown or arguments invalid
*/
int
imap4d_logout (struct imap4d_command *command, char *arg)
imap4d_logout (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
imap4d_bye0 (OK, command);
return 0;
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,13 +19,20 @@
#include "imap4d.h"
/*
*
*/
6.3.9. LSUB Command
Arguments: reference name
mailbox name with possible wildcards
Responses: untagged responses: LSUB
Result: OK - lsub completed
NO - lsub failure: can't list that reference or name
BAD - command unknown or arguments invalid
*/
int
imap4d_lsub (struct imap4d_command *command, char *arg)
imap4d_lsub (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp;
char *ref;
char *wcard;
char *file = NULL;
......@@ -33,14 +40,11 @@ imap4d_lsub (struct imap4d_command *command, char *arg)
const char *delim = "/";
FILE *fp;
ref = util_getword (arg, &sp);
wcard = util_getword (NULL, &sp);
if (!ref || !wcard)
return util_finish (command, RESP_BAD, "Too few arguments");
if (imap4d_tokbuf_argc (tok) != 4)
return util_finish (command, RESP_BAD, "Invalid arguments");
/* Remove the double quotes. */
util_unquote (&ref);
util_unquote (&wcard);
ref = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
wcard = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2);
asprintf (&pattern, "%s%s", ref, wcard);
if (!pattern)
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -89,8 +89,9 @@ print_namespace (int n)
util_send ("(");
for (i = 0; i < namespace[n].subdir_c; i++)
{
util_send ("(\"%s\" \"/\")",
printable_pathname (namespace[n].subdir_v[i]));
char *dir = printable_pathname (namespace[n].subdir_v[i]);
char *suf = (dir[0] && dir[strlen (dir) - 1] != '/') ? "/" : "";
util_send ("(\"%s%s\" \"/\")", dir, suf);
}
util_send (")");
}
......@@ -114,11 +115,27 @@ namespace_enumerate_all (nsfp_t f, void *closure)
|| namespace_enumerate (NS_SHARED, f, closure);
}
/*
5. NAMESPACE Command
Arguments: none
Response: an untagged NAMESPACE response that contains the prefix
and hierarchy delimiter to the server's Personal
Namespace(s), Other Users' Namespace(s), and Shared
Namespace(s) that the server wishes to expose. The
response will contain a NIL for any namespace class
that is not available. Namespace_Response_Extensions
MAY be included in the response.
Namespace_Response_Extensions which are not on the IETF
standards track, MUST be prefixed with an "X-".
*/
int
imap4d_namespace (struct imap4d_command *command, char *arg)
imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
if (*arg)
return util_finish (command, RESP_BAD, "Too many arguments");
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
util_send ("* NAMESPACE ");
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,13 +19,10 @@
#include "imap4d.h"
int
imap4d_noop (struct imap4d_command *command, char *arg)
imap4d_noop (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
imap4d_sync ();
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,30 +19,37 @@
#include "imap4d.h"
/*
6.3.5. RENAME Command
Arguments: existing mailbox name
new mailbox name
Responses: no specific responses for this command
Result: OK - rename completed
NO - rename failure: can't rename mailbox with that name,
can't rename to mailbox with that name
BAD - command unknown or arguments invalid
*/
/*
FIXME: Renaming a mailbox we must change the UIDVALIDITY
of the mailbox. */
int
imap4d_rename (struct imap4d_command *command, char *arg)
imap4d_rename (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *oldname;
char *newname;
char *sp = NULL;
int rc = RESP_OK;
const char *msg = "Completed";
struct stat newst;
const char *delim = "/";
oldname = util_getword (arg, &sp);
newname = util_getword (NULL, &sp);
if (!newname || !oldname)
return util_finish (command, RESP_BAD, "Too few arguments");
util_unquote (&newname);
util_unquote (&oldname);
if (imap4d_tokbuf_argc (tok) != 4)
return util_finish (command, RESP_BAD, "Invalid arguments");
if (*newname == '\0' || *oldname == '\0')
return util_finish (command, RESP_BAD, "Too few arguments");
oldname = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
newname = imap4d_tokbuf_getarg (tok, IMAP4_ARG_2);
if (strcasecmp (newname, "INBOX") == 0)
return util_finish (command, RESP_NO, "Name Inbox is reservered");
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2002, 2005, 2007,
2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -223,11 +224,9 @@ struct mem_chain
/* Parse buffer structure */
struct parsebuf
{
char *token; /* Current token. Either points to tokbuf
or is allocated within `alloc' chain */
char tokbuf[MAXTOKEN+1]; /* Token buffer for short tokens */
char *arg; /* Rest of command line to be parsed */
imap4d_tokbuf_t tok; /* Token buffer */
int arg; /* Argument number */
char *token; /* Current token */
int isuid; /* UIDs instead of msgnos are required */
char *err_mesg; /* Error message if a parse error occured */
struct mem_chain *alloc; /* Chain of objects allocated during parsing */
......@@ -249,30 +248,45 @@ static int parse_gettoken (struct parsebuf *pb, int req);
static int search_run (struct parsebuf *pb);
static void do_search (struct parsebuf *pb);
/*
6.4.4. SEARCH Command
Arguments: OPTIONAL [CHARSET] specification
searching criteria (one or more)
Responses: REQUIRED untagged response: SEARCH
Result: OK - search completed
NO - search error: can't search that [CHARSET] or
criteria
BAD - command unknown or arguments invalid
*/
int
imap4d_search (struct imap4d_command *command, char *arg)
imap4d_search (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int rc;
char buffer[64];
char *err_text= "";
rc = imap4d_search0 (arg, 0, buffer, sizeof buffer);
return util_finish (command, rc, "%s", buffer);
rc = imap4d_search0 (tok, 0, &err_text);
return util_finish (command, rc, "%s", err_text);
}
int
imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize)
imap4d_search0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
{
struct parsebuf parsebuf;
memset (&parsebuf, 0, sizeof(parsebuf));
parsebuf.arg = arg;
parsebuf.tok = tok;
parsebuf.arg = IMAP4_ARG_1 + !!isuid;
parsebuf.err_mesg = NULL;
parsebuf.alloc = NULL;
parsebuf.isuid = isuid;
if (!parse_gettoken (&parsebuf, 0))
{
snprintf (replybuf, replysize, "Too few args");
*err_text = "Too few args";
return RESP_BAD;
}
......@@ -280,20 +294,20 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize)
{
if (!parse_gettoken (&parsebuf, 0))
{
snprintf (replybuf, replysize, "Too few args");
*err_text = "Too few args";
return RESP_BAD;
}
/* Currently only ASCII is supported */
if (strcasecmp (parsebuf.token, "US-ASCII"))
{
snprintf (replybuf, replysize, "Charset not supported");
*err_text = "Charset not supported";
return RESP_NO;
}
if (!parse_gettoken (&parsebuf, 0))
{
snprintf (replybuf, replysize, "Too few args");
*err_text = "Too few args";
return RESP_BAD;
}
......@@ -304,16 +318,14 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize)
if (!parsebuf.tree)
{
parse_free_mem (&parsebuf);
snprintf (replybuf, replysize, "%s (near %s)",
parsebuf.err_mesg,
*parsebuf.arg ? parsebuf.arg : "end");
*err_text = "Parse error";
return RESP_BAD;
}
if (parsebuf.token[0] != 0)
if (parsebuf.token)
{
parse_free_mem (&parsebuf);
snprintf (replybuf, replysize, "Junk at the end of statement");
*err_text = "Junk at the end of statement";
return RESP_BAD;
}
......@@ -322,7 +334,7 @@ imap4d_search0 (char *arg, int isuid, char *replybuf, size_t replysize)
parse_free_mem (&parsebuf);
snprintf (replybuf, replysize, "Completed");
*err_text = "Completed";
return RESP_OK;
}
......@@ -359,41 +371,13 @@ do_search (struct parsebuf *pb)
int
parse_gettoken (struct parsebuf *pb, int req)
{
int rc;
char *s;
pb->token = pb->tokbuf;
while (*pb->arg && *pb->arg == ' ')
pb->arg++;
switch (*pb->arg)
if (req && pb->arg >= imap4d_tokbuf_argc (pb->tok))
{
case '(':
case ')':
pb->token[0] = *pb->arg++;
pb->token[1] = 0;
rc = 1;
break;
case '"':
s = ++pb->arg;
while (*pb->arg && *pb->arg != '"')
pb->arg++;
rc = pb->arg - s;
if (*pb->arg)
pb->arg++;
if (rc >= sizeof(pb->tokbuf))
pb->token = parse_alloc (pb, rc+1);
memcpy (pb->token, s, rc);
pb->token[rc] = 0;
break;
default:
rc = util_token (pb->token, sizeof(pb->tokbuf), &pb->arg);
break;
}
if (req && rc == 0)
pb->err_mesg = "Unexpected end of statement";
return rc;
return 0;
}
pb->token = imap4d_tokbuf_getarg (pb->tok, pb->arg++);
return 1;
}
/* Memory handling */
......@@ -468,7 +452,7 @@ parse_search_key_list (struct parsebuf *pb)
{
struct search_node *leftarg = NULL;
while (pb->token[0] && pb->token[0] != ')')
while (pb->token && pb->token[0] != ')')
{
struct search_node *rightarg = parse_search_key (pb);
if (!rightarg)
......@@ -563,8 +547,8 @@ parse_equiv_key (struct parsebuf *pb)
{
struct search_node *node;
struct cond_equiv *condp;
char *arg;
char *save_arg;
int save_arg;
imap4d_tokbuf_t save_tok;
for (condp = equiv_list; condp->name && strcasecmp (condp->name, pb->token);
condp++)
......@@ -574,8 +558,9 @@ parse_equiv_key (struct parsebuf *pb)
return parse_simple_key (pb);
save_arg = pb->arg;
arg = parse_strdup (pb, condp->equiv);
pb->arg = arg;
save_tok = pb->tok;
pb->tok = imap4d_tokbuf_from_string (condp->equiv);
pb->arg = 0;
parse_gettoken (pb, 0);
......@@ -587,8 +572,10 @@ parse_equiv_key (struct parsebuf *pb)
__FILE__, __LINE__);
abort ();
}
imap4d_tokbuf_destroy (&pb->tok);
pb->arg = save_arg;
pb->tok = save_tok;
parse_gettoken (pb, 0);
return node;
}
......@@ -658,7 +645,7 @@ parse_simple_key (struct parsebuf *pb)
return NULL;
}
if (!pb->token[0])
if (!pb->token)
{
pb->err_mesg = "Not enough arguments for criterion";
return NULL;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2003, 2005, 2006,
2007 Free Software Foundation, Inc.
2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -24,25 +24,22 @@ static int select_flags;
/* select ::= "SELECT" SPACE mailbox */
int
imap4d_select (struct imap4d_command *command, char *arg)
imap4d_select (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
return imap4d_select0 (command, arg, MU_STREAM_RDWR);
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
return imap4d_select0 (command, imap4d_tokbuf_getarg (tok, IMAP4_ARG_1),
MU_STREAM_RDWR);
}
/* This code is share with EXAMINE. */
int
imap4d_select0 (struct imap4d_command *command, char *arg, int flags)
imap4d_select0 (struct imap4d_command *command, char *mailbox_name, int flags)
{
char *mailbox_name, *sp = NULL;
int status;
/* FIXME: Check state. */
mailbox_name = util_getword (arg, &sp);
util_unquote (&mailbox_name);
if (mailbox_name == NULL || *mailbox_name == '\0')
return util_finish (command, RESP_BAD, "Too few arguments");
/* Even if a mailbox is selected, a SELECT EXAMINE or LOGOUT
command MAY be issued without previously issuing a CLOSE command.
The SELECT, EXAMINE, and LOGUT commands implictly close the
......
......@@ -23,17 +23,26 @@
static int tls_available;
static int tls_done;
/*
6.2.1. STARTTLS Command
Arguments: none
Responses: no specific response for this command
Result: OK - starttls completed, begin TLS negotiation
BAD - command unknown or arguments invalid
*/
int
imap4d_starttls (struct imap4d_command *command, char *arg)
imap4d_starttls (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int status;
char *sp = NULL;
if (!tls_available || tls_done)
return util_finish (command, RESP_BAD, "Invalid command");
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
util_atexit (mu_deinit_tls_libs);
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -53,10 +53,21 @@ status_get_handler (const char *name)
return NULL;
}
/*
6.3.10. STATUS Command
Arguments: mailbox name
status data item names
Responses: untagged responses: STATUS
Result: OK - status completed
NO - status failure: no status for that name
BAD - command unknown or arguments invalid
*/
int
imap4d_status (struct imap4d_command *command, char *arg)
imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
char *name;
char *mailbox_name;
const char *delim = "/";
......@@ -64,11 +75,12 @@ imap4d_status (struct imap4d_command *command, char *arg)
int status;
int count = 0;
char *err_msg = NULL;
int argc = imap4d_tokbuf_argc (tok);
if (argc < 4)
return util_finish (command, RESP_BAD, "Invalid arguments");
name = util_getword (arg, &sp);
util_unquote (&name);
if (!name || *name == '\0' || !sp || *sp == '\0')
return util_finish (command, RESP_BAD, "Too few args");
name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
mailbox_name = namespace_getfullpath (name, delim);
......@@ -85,20 +97,22 @@ imap4d_status (struct imap4d_command *command, char *arg)
status = mu_mailbox_open (smbox, MU_STREAM_READ);
if (status == 0)
{
char item[32];
item[0] = '\0';
int i = IMAP4_ARG_2;
char *item = imap4d_tokbuf_getarg (tok, i);
if (*sp == '(')
sp++;
else
*sp = 0;
if (item[0] == '(')
{
if (imap4d_tokbuf_getarg (tok, argc - 1)[0] != ')')
return util_finish (command, RESP_BAD, "Invalid arguments");
argc--;
i++;
}
/* Get the status item names. */
while (*sp && *sp != ')')
for (; i < argc; i++)
{
status_funcp fun;
util_token (item, sizeof (item), &sp);
item = imap4d_tokbuf_getarg (tok, i);
fun = status_get_handler (item);
if (!fun)
{
......@@ -112,6 +126,8 @@ imap4d_status (struct imap4d_command *command, char *arg)
if (!fun (smbox))
util_send (" ");
}
if (count > 0)
util_send (")\r\n");
mu_mailbox_close (smbox);
......@@ -193,5 +209,4 @@ status_unseen (mu_mailbox_t smbox)
}
util_send ("UNSEEN %d", unseen);
return 0;
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2005, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2005, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -23,134 +23,155 @@
*/
int
imap4d_store (struct imap4d_command *command, char *arg)
imap4d_store (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
int rc;
char buffer[64];
char *err_text;
rc = imap4d_store0 (arg, 0, buffer, sizeof buffer);
return util_finish (command, rc, "%s", buffer);
rc = imap4d_store0 (tok, 0, &err_text);
return util_finish (command, rc, "%s", err_text);
}
struct parsebuf
{
char *token;
imap4d_tokbuf_t tok;
int arg;
jmp_buf errjmp;
char *err_text;
};
static void
parsebuf_exit (struct parsebuf *p, char *text)
{
p->err_text = text;
longjmp (p->errjmp, 1);
}
static char *
parsebuf_next (struct parsebuf *p, int req)
{
p->token = imap4d_tokbuf_getarg (p->tok, p->arg++);
if (!p->token && req)
parsebuf_exit (p, "Too few arguments");
return p->token;
}
int
imap4d_store0 (char *arg, int isuid, char *resp, size_t resplen)
imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext)
{
char *msgset;
char *data;
char *sp = NULL;
int status;
int ack = 0;
int ack = 1;
size_t i;
int n = 0;
size_t *set = NULL;
enum value_type { STORE_SET, STORE_ADD, STORE_UNSET } how;
struct parsebuf pb;
char *data;
int type = 0;
msgset = util_getword (arg, &sp);
data = util_getword (NULL, &sp);
if (!msgset || !data || !sp || *sp == '\0')
pb.tok = tok;
pb.arg = IMAP4_ARG_1;
pb.err_text = NULL;
if (setjmp (pb.errjmp))
{
snprintf (resp, resplen, "Too few args");
*ptext = pb.err_text;
free (set);
return RESP_BAD;
}
/* The parsing of the data-item is a little slugish. */
if (strcasecmp (data, "FLAGS") == 0)
{
ack = 1;
how = STORE_SET;
}
else if (strcasecmp (data, "+FLAGS") == 0)
msgset = parsebuf_next (&pb, 1);
data = parsebuf_next (&pb, 1);
if (*data == '+')
{
ack = 1;
how = STORE_ADD;
data++;
}
else if (strcasecmp (data, "-FLAGS") == 0)
else if (*data == '-')
{
ack = 1;
how = STORE_UNSET;
data++;
}
else if (strcasecmp (data, "FLAGS.SILENT") == 0)
{
ack = 0;
else
how = STORE_SET;
}
else if (strcasecmp (data, "+FLAGS.SILENT") == 0)
if (strcasecmp (data, "FLAGS"))
parsebuf_exit (&pb, "Bogus data item");
data = parsebuf_next (&pb, 1);
if (*data == '.')
{
ack = 0;
how = STORE_ADD;
}
else if (strcasecmp (data, "-FLAGS.SILENT") == 0)
data = parsebuf_next (&pb, 1);
if (strcasecmp (data, "SILENT") == 0)
{
ack = 0;
how = STORE_UNSET;
parsebuf_next (&pb, 1);
}
else
{
snprintf (resp, resplen, "Bogus data item");
return RESP_BAD;
parsebuf_exit (&pb, "Bogus data suffix");
}
/* Get the message numbers in set[]. */
status = util_msgset (msgset, &set, &n, isuid);
if (status != 0)
parsebuf_exit (&pb, "Bogus number set");
if (pb.token[0] != '(')
parsebuf_exit (&pb, "Syntax error");
parsebuf_next (&pb, 1);
do
{
snprintf (resp, resplen, "Bogus number set");
return RESP_BAD;
int t;
if (!util_attribute_to_type (pb.token, &t))
type |= t;
}
while (parsebuf_next (&pb, 1) && pb.token[0] != ')');
for (i = 0; i < n; i++)
{
mu_message_t msg = NULL;
mu_attribute_t attr = NULL;
char *items = strdup (sp); /* Don't use the orignal list. */
int first = 1;
size_t msgno;
char *p = items;
size_t msgno = isuid ? uid_to_msgno (set[i]) : set[i];
msgno = (isuid) ? uid_to_msgno (set[i]) : set[i];
if (msgno)
{
mu_mailbox_get_message (mbox, msgno, &msg);
mu_message_get_attribute (msg, &attr);
/* Get the fetch command names. */
while (*items && *items != ')')
switch (how)
{
int type = 0;
char item[64] = "";
util_token (item, sizeof (item), &items);
if (!util_attribute_to_type (item, &type))
{
if (how == STORE_ADD )
case STORE_ADD:
mu_attribute_set_flags (attr, type);
else if (how == STORE_UNSET )
break;
case STORE_UNSET:
mu_attribute_unset_flags (attr, type);
else if (how == STORE_SET )
{
if (first)
{
mu_attribute_set_flags (attr, 0);
first = 0;
}
break;
case STORE_SET:
mu_attribute_unset_flags (attr, 0xffffffff); /* FIXME */
mu_attribute_set_flags (attr, type);
}
mu_attribute_set_flags (attr, MU_ATTRIBUTE_MODIFIED);
}
}
}
if (ack)
{
util_send ("* %d FETCH (", msgno);
fetch_flags0 ("FLAGS", msg, isuid);
util_send (")\r\n");
if (isuid)
util_send ("UID %lu ", (unsigned long) msgno);
util_send ("FLAGS (");
util_print_flags (attr);
util_send ("))\r\n");
}
free (p);
/* Update the flags of uid table. */
imap4d_sync_flags (set[i]);
}
free (set);
snprintf (resp, resplen, "Completed");
*ptext = "Completed";
return RESP_OK;
}
......
......@@ -19,21 +19,27 @@
#include "imap4d.h"
/*
FIXME: We need to lock the file to prevent simultaneous access.
*/
6.3.6. SUBSCRIBE Command
Arguments: mailbox
Responses: no specific responses for this command
Result: OK - subscribe completed
NO - subscribe failure: can't subscribe to that name
BAD - command unknown or arguments invalid
*/
int
imap4d_subscribe (struct imap4d_command *command, char *arg)
imap4d_subscribe (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
char *name;
char *file;
FILE *fp;
name = util_getword (arg, &sp);
util_unquote (&name);
if (!name || *name == '\0')
return util_finish (command, RESP_BAD, "Too few arguments");
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
asprintf (&file, "%s/.mailboxlist", homedir);
fp = fopen (file, "a");
......
# -*- tcl -*-
# This file is part of Mailutils testsuite.
# Copyright (C) 2002, 2007 Free Software Foundation
# Copyright (C) 2002, 2007, 2008 Free Software Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -20,7 +20,7 @@
imap4d_start
imap4d_test "CAPABILITY" \
"CAPABILITY IMAP4rev1 NAMESPACE IDLE X-VERSION" \
"CAPABILITY IMAP4rev1 NAMESPACE IDLE LITERAL+ X-VERSION" \
"OK"
imap4d_test "NOOP"
......
......@@ -48,7 +48,7 @@ Hello Joe, do you think we can meet at 3:30 tomorrow?
"
imap4d_test -long "APPEND mbox 25-Aug-2002 18:00:00 +0200"\
imap4d_test -long "APPEND mbox \"25-Aug-2002 18:00:00 +0200\""\
"Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
From: Fred Foobar <foobar@Blurdybloop.COM>
Subject: afternoon meeting again
......@@ -72,7 +72,7 @@ imap4d_test "SELECT mbox"\
"OK"
imap4d_test "FETCH 2:3 BODY\[\]"\
"2 FETCH (FLAGS (\\Seen) BODY\[\] {310}"\
"2 FETCH (FLAGS (\\Seen) BODY\[\] {312}"\
-literal\
"Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)"\
"From: Fred Foobar <foobar@Blurdybloop.COM>"\
......@@ -83,9 +83,10 @@ imap4d_test "FETCH 2:3 BODY\[\]"\
"Content-Type: TEXT/PLAIN; CHARSET=US-ASCII"\
""\
"Hello Joe, do you think we can meet at 3:30 tomorrow?"\
""\
")"\
-noliteral\
"3 FETCH (FLAGS (\\Seen) BODY\[\] {283}"\
"3 FETCH (FLAGS (\\Seen) BODY\[\] {285}"\
-literal\
"Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)"\
"From: Fred Foobar <foobar@Blurdybloop.COM>"\
......
......@@ -37,7 +37,7 @@ imap4d_test "CREATE flat"
imap4d_test "CREATE en/to/tre"
imap4d_test -long "APPEND en/to/tre 25-Aug-2002 18:00:00 +0200"\
imap4d_test -long "APPEND en/to/tre \"25-Aug-2002 18:00:00 +0200\""\
"Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST)
From: Fred Foobar <foobar@Blurdybloop.COM>
Subject: afternoon meeting again
......@@ -65,7 +65,7 @@ imap4d_test "SELECT en/to/tre"\
"OK \[READ-WRITE\] SELECT Completed"
imap4d_test "FETCH 1 ALL"\
"1 FETCH (FLAGS (\\Recent) INTERNALDATE \"25-Aug-2002 16:00:00 +0000\" RFC822.SIZE 283 ENVELOPE (\"Mon, 7 Feb 1994 21:52:25 -0800 (PST)\" \"afternoon meeting again\" ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((NIL NIL \"mooch\" \"owatagu.siam.edu\")) NIL NIL NIL \"<B27397-0200000@Blurdybloop.COM>\"))"\
"1 FETCH (FLAGS (\\Recent) INTERNALDATE \"25-Aug-2002 16:00:00 +0000\" RFC822.SIZE 285 ENVELOPE (\"Mon, 7 Feb 1994 21:52:25 -0800 (PST)\" \"afternoon meeting again\" ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((\"Fred Foobar\" NIL \"foobar\" \"Blurdybloop.COM\")) ((NIL NIL \"mooch\" \"owatagu.siam.edu\")) NIL NIL NIL \"<B27397-0200000@Blurdybloop.COM>\"))"\
"OK"
......
......@@ -165,7 +165,7 @@ imap4d_test "FETCH 1 BODY\[HEADER\]"\
# The subset returned by HEADER.FIELDS contains only those header fields
# with a field-name that matches one of the names in the list;
imap4d_test "FETCH 1 BODY\[HEADER.FIELDS FROM TO SUBJECT\]"\
imap4d_test "FETCH 1 BODY\[HEADER.FIELDS (FROM TO SUBJECT)\]"\
"1 FETCH (BODY\[HEADER.FIELDS (\"FROM\" \"TO\" \"SUBJECT\")\] {94}"\
-literal\
"FROM: Foo Bar <foobar@nonexistent.net>"\
......@@ -178,7 +178,7 @@ imap4d_test "FETCH 1 BODY\[HEADER.FIELDS FROM TO SUBJECT\]"\
# similarly, the subset returned by HEADER.FIELDS.NOT contains only
# the header fields with a non-matching field-name.
imap4d_test "FETCH 1 BODY\[HEADER.FIELDS.NOT FROM TO SUBJECT\]"\
imap4d_test "FETCH 1 BODY\[HEADER.FIELDS.NOT (FROM TO SUBJECT)\]"\
"1 FETCH (BODY\[HEADER.FIELDS.NOT (\"FROM\" \"TO\" \"SUBJECT\")\] {235}"\
-literal\
"Received: (from foobar@nonexistent.net) "\
......@@ -330,8 +330,13 @@ imap4d_test "FETCH 3 BODY\[1.MIME\]"\
"OK"
imap4d_test "FETCH 4 BODY\[2.2.1\]"\
"4 FETCH (FLAGS (\\Seen) BODY\[2.2.1\] {490}"\
"4 FETCH (FLAGS (\\Seen) BODY\[2.2.1\] {680}"\
-literal\
"Content-Type: application/octet-stream; name=\"msg.23\""\
"Content-ID: <5122.1026510654.6@Mirddin.farlep.net>"\
"Content-Description: Father William Part III"\
"Content-Transfer-Encoding: base64"\
""\
"YFlvdSBhcmUgb2xkLCcgc2FpZCB0aGUgeW91dGgsIGBhbmQgeW91ciBqYXdzIGFyZSB0b28gd2Vh"\
"awpGb3IgYW55dGhpbmcgdG91Z2hlciB0aGFuIHN1ZXQ7CllldCB5b3UgZmluaXNoZWQgdGhlIGdv"\
"b3NlLCB3aXRoIHRoZSBib25lcyBhbmQgdGhlIGJlYWstLQpQcmF5IGhvdyBkaWQgeW91IG1hbmFn"\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -24,36 +24,29 @@
*/
int
imap4d_uid (struct imap4d_command *command, char *arg)
imap4d_uid (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *cmd;
char *sp = NULL;
int rc = RESP_NO;
char buffer[64];
char *err_text = "Completed";
if (imap4d_tokbuf_argc (tok) < 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
cmd = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
cmd = util_getword (arg, &sp);
if (!cmd)
util_finish (command, RESP_BAD, "Too few args");
if (strcasecmp (cmd, "FETCH") == 0)
{
rc = imap4d_fetch0 (sp, 1, buffer, sizeof buffer);
}
rc = imap4d_fetch0 (tok, 1, &err_text);
else if (strcasecmp (cmd, "COPY") == 0)
{
rc = imap4d_copy0 (sp, 1, buffer, sizeof buffer);
}
rc = imap4d_copy0 (tok, 1, &err_text);
else if (strcasecmp (cmd, "STORE") == 0)
{
rc = imap4d_store0 (sp, 1, buffer, sizeof buffer);
}
rc = imap4d_store0 (tok, 1, &err_text);
else if (strcasecmp (cmd, "SEARCH") == 0)
{
rc = imap4d_search0 (sp, 1, buffer, sizeof buffer);
}
rc = imap4d_search0 (tok, 1, &err_text);
else
{
snprintf (buffer, sizeof buffer, "Error uknown uid command");
err_text = "Uknown uid command";
rc = RESP_BAD;
}
return util_finish (command, rc, "%s %s", cmd, buffer);
return util_finish (command, rc, "%s %s", cmd, err_text);
}
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -71,19 +71,34 @@ unsubscribe (struct scan_data *data, char *name)
return 0;
}
/*
6.3.7. UNSUBSCRIBE Command
Arguments: mailbox name
Responses: no specific responses for this command
Result: OK - unsubscribe completed
NO - unsubscribe failure: can't unsubscribe that name
BAD - command unknown or arguments invalid
The UNSUBSCRIBE command removes the specified mailbox name from
the server's set of "active" or "subscribed" mailboxes as returned
by the LSUB command. This command returns a tagged OK response
only if the unsubscription is successful.
*/
int
imap4d_unsubscribe (struct imap4d_command *command, char *arg)
imap4d_unsubscribe (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
char *sp = NULL;
char *name;
char *file;
struct scan_data sd;
int rc;
name = util_getword (arg, &sp);
util_unquote (&name);
if (!name || *name == '\0')
return util_finish (command, RESP_BAD, "Too few arguments");
if (imap4d_tokbuf_argc (tok) != 3)
return util_finish (command, RESP_BAD, "Invalid arguments");
name = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
asprintf (&file, "%s/.mailboxlist", homedir);
sd.result = 0;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999, 2001, 2007 Free Software Foundation, Inc.
Copyright (C) 1999, 2001, 2007, 2008 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -19,8 +19,10 @@
#include "imap4d.h"
int
imap4d_version (struct imap4d_command *command, char *arg)
imap4d_version (struct imap4d_command *command, imap4d_tokbuf_t tok)
{
if (imap4d_tokbuf_argc (tok) != 2)
return util_finish (command, RESP_BAD, "Invalid arguments");
util_send ("* %s GNU %s\r\n", command->name, program_version);
return util_finish (command, RESP_OK, "Completed");
}
......
......@@ -145,7 +145,7 @@ mail_tmp_finish (struct mail_tmp *mtmp, mu_mailbox_t *mbox)
}
mu_stream_flush (mtmp->stream);
if ((status = mu_mailbox_create (mbox, "/dev/null"))
if ((status = mu_mailbox_create (mbox, "mbox:/dev/null"))
|| (status = mu_mailbox_open (*mbox, MU_STREAM_READ))
|| (status = mu_mailbox_set_stream (*mbox, mtmp->stream)))
{
......
......@@ -51,7 +51,7 @@ _memory_destroy (mu_stream_t stream)
struct _memory_stream *mfs = mu_stream_get_owner (stream);
if (mfs && mfs->ptr != NULL)
free (mfs->ptr);
if(mfs->filename)
if (mfs->filename)
free (mfs->filename);
free (mfs);
}
......