Commit 86506722 865067223c5fe78dd2b48b3aa1496fcd2a7ae5fd by Jakob Kaivo

more imap4d infrastructure

1 parent e4695e88
......@@ -24,6 +24,7 @@
int
imap4d_append (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,11 @@
#include "imap4d.h"
/*
*
* What types of auth should be supported?
*/
int
imap4d_authenticate (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
return util_finish (argc, argv, RESP_NO, NULL, "Type not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
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
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "imap4d.h"
int
imap4d_capability (int argc, char **argv)
{
if (argc > 2)
return TOO_MANY;
util_out (argv[0], TAG_NONE, "CAPABILITY IMAP4rev1");
return util_finish (argc, argv, RESP_OK, NULL, "Completed");
}
......@@ -18,12 +18,13 @@
#include "imap4d.h"
/*
*
* Do we need to do anything here?
*/
int
imap4d_check (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 2)
return TOO_MANY;
return util_finish (argc, argc, RESP_OK, NULL, "Completed");
}
......
......@@ -24,6 +24,7 @@
int
imap4d_close (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 2)
return TOO_MANY;
return NOT_IMPL;
}
......
......@@ -18,29 +18,29 @@
#include "imap4d.h"
const struct imap4d_command imap4d_command_table [] = {
{ "capability", imap4d_capability, STATE_ALL },
{ "noop", imap4d_noop, STATE_ALL },
{ "logout", imap4d_logout, STATE_ALL },
{ "authenticate", imap4d_authenticate, STATE_NONAUTH },
{ "login", imap4d_login, STATE_NONAUTH },
{ "select", imap4d_select, STATE_AUTH | STATE_SEL },
{ "examine", imap4d_examine, STATE_AUTH | STATE_SEL },
{ "create", imap4d_create, STATE_AUTH | STATE_SEL },
{ "delete", imap4d_delete, STATE_AUTH | STATE_SEL },
{ "rename", imap4d_rename, STATE_AUTH | STATE_SEL },
{ "subscribe", imap4d_subscribe, STATE_AUTH | STATE_SEL },
{ "unsubscribe", imap4d_unsubscribe, STATE_AUTH | STATE_SEL },
{ "list", imap4d_list, STATE_AUTH | STATE_SEL },
{ "lsub", imap4d_lsub, STATE_AUTH | STATE_SEL },
{ "status", imap4d_status, STATE_AUTH | STATE_SEL },
{ "append", imap4d_append, STATE_AUTH | STATE_SEL },
{ "check", imap4d_check, STATE_SEL },
{ "close", imap4d_close, STATE_SEL },
{ "expunge", imap4d_expunge, STATE_SEL },
{ "search", imap4d_search, STATE_SEL },
{ "fetch", imap4d_fetch, STATE_SEL },
{ "store", imap4d_store, STATE_SEL },
{ "copy", imap4d_copy, STATE_SEL },
{ "uid", imap4d_uid, STATE_SEL },
{ "capability", imap4d_capability, STATE_ALL, STATE_NONE, STATE_NONE },
{ "noop", imap4d_noop, STATE_ALL, STATE_NONE, STATE_NONE },
{ "logout", imap4d_logout, STATE_ALL, STATE_LOGOUT, STATE_NONE },
{ "authenticate", imap4d_authenticate, STATE_NONAUTH, STATE_NONE, STATE_AUTH },
{ "login", imap4d_login, STATE_NONAUTH, STATE_NONE, STATE_AUTH },
{ "select", imap4d_select, STATE_AUTH | STATE_SEL, STATE_AUTH, STATE_SEL },
{ "examine", imap4d_examine, STATE_AUTH | STATE_SEL, STATE_AUTH, STATE_SEL },
{ "create", imap4d_create, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "delete", imap4d_delete, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "rename", imap4d_rename, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "subscribe", imap4d_subscribe, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "unsubscribe", imap4d_unsubscribe, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "list", imap4d_list, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "lsub", imap4d_lsub, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "status", imap4d_status, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "append", imap4d_append, STATE_AUTH | STATE_SEL, STATE_NONE, STATE_NONE },
{ "check", imap4d_check, STATE_SEL, STATE_NONE, STATE_NONE },
{ "close", imap4d_close, STATE_SEL, STATE_AUTH, STATE_AUTH },
{ "expunge", imap4d_expunge, STATE_SEL, STATE_NONE, STATE_NONE },
{ "search", imap4d_search, STATE_SEL, STATE_NONE, STATE_NONE },
{ "fetch", imap4d_fetch, STATE_SEL, STATE_NONE, STATE_NONE },
{ "store", imap4d_store, STATE_SEL, STATE_NONE, STATE_NONE },
{ "copy", imap4d_copy, STATE_SEL, STATE_NONE, STATE_NONE },
{ "uid", imap4d_uid, STATE_SEL, STATE_NONE, STATE_NONE },
{ 0, 0, 0}
};
......
......@@ -18,12 +18,15 @@
#include "imap4d.h"
/*
*
* copy messages in argv[2] to mailbox in argv[3]
*/
int
imap4d_copy (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 4)
return TOO_MANY;
else if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,15 @@
#include "imap4d.h"
/*
*
* must create a new mailbox
*/
int
imap4d_create (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 3)
return TOO_MANY;
else if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -24,6 +24,9 @@
int
imap4d_delete (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 3)
return TOO_MANY;
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,11 @@
#include "imap4d.h"
/*
*
* copy things from select.c
*/
int
imap4d_examine (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
return NOT_IMPL;
}
......
......@@ -24,6 +24,7 @@
int
imap4d_expunge (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 2)
return TOO_MANY;
return NOT_IMPL;
}
......
......@@ -18,12 +18,14 @@
#include "imap4d.h"
/*
*
* This will suck, too
*/
int
imap4d_fetch (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc < 4)
return TOO_FEW;
/* check for paren list */
return NOT_IMPL;
}
......
......@@ -66,6 +66,8 @@ struct imap4d_command {
char *name;
Function *func;
int states;
int success;
int failure;
};
/* Global variables and constants*/
......@@ -87,6 +89,10 @@ struct imap4d_command {
extern const struct imap4d_command imap4d_command_table[];
#define TOO_MANY (util_finish (argc, argv, RESP_BAD, NULL, "Too many args"))
#define TOO_FEW (util_finish (argc, argv, RESP_BAD, NULL, "Too few args"))
#define NOT_IMPL (util_finish (argc, argv, RESP_BAD, NULL, "Not implemented"))
/* Functions */
int imap4d_capability __P ((int argc, char **argv));
int imap4d_noop __P ((int argc, char **argv));
......@@ -115,8 +121,9 @@ int imap4d_uid __P ((int argc, char **argv));
int util_out __P ((char *seq, int tag, char *f, ...));
int util_start __P ((char *seq));
int util_finish __P ((int argc, char **argv, int resp, char *f, ...));
int util_getstate __P((void));
int util_finish __P ((int argc, char **argv, int resp, char *r, char *f, ...));
int util_getstate __P ((void));
struct imap4d_command *util_getcommand __P ((char *cmd));
#ifdef __cplusplus
}
......
......@@ -24,6 +24,9 @@
int
imap4d_list (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 4)
return TOO_MANY;
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,17 @@
#include "imap4d.h"
/*
*
* argv[2] == username
* argv[3] == password
* this should support PAM, shadow, and normal password
*/
int
imap4d_login (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argv > 4)
return TOO_MANY;
else if (argv < 4)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,15 @@
#include "imap4d.h"
/*
*
* This needs to properly close the mailbox
*/
int
imap4d_logout (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 2)
return TOO_MANY;
util_out (argv[0], TAG_NONE, "BYE Logging out");
util_finish (argc, argv, RESP_OK, NULL, "Completed");
exit (0);
}
......
......@@ -24,6 +24,9 @@
int
imap4d_lsub (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 4)
return TOO_MANY;
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -17,14 +17,10 @@
#include "imap4d.h"
/*
*
*/
int
imap4d_noop (int argc, char **argv)
{
if (argc > 2)
return util_finish (argc, argv, RESP_BAD, "Too many arguments");
return util_finish (argc, argv, RESP_OK, "Completed");
return TOO_MANY;
return util_finish (argc, argv, RESP_OK, NULL, "Completed");
}
......
......@@ -24,6 +24,9 @@
int
imap4d_rename (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 4)
return TOO_MANY;
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,13 @@
#include "imap4d.h"
/*
*
* This will be a royal pain in the arse to implement
*/
int
imap4d_search (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,27 @@
#include "imap4d.h"
/*
*
* argv[2] == mailbox
* this needs to share code with EXAMINE
*/
int
imap4d_select (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 3)
return TOO_MANY;
else if (argc < 3)
return TOO_FEW;
/* close previous mailbox */
if ( /* open mailbox (argv[2]) == */ 0)
{
char *flags = NULL;
int num_messages = 0, recent = 0, uid = 0;
util_out (argv[0], TAG_NONE, "FLAGS %s", flags);
util_out (argv[0], TAG_NONE, "%d EXISTS", num_messages);
util_out (argv[0], TAG_NONE, "%d RECENT", recent);
return util_finish (argc, argv, RESP_OK, NULL, "Complete");
}
return util_finish (argc, argv, RESP_NO, NULL, "Couldn't open %s", argv[2]);
}
......
......@@ -24,6 +24,9 @@
int
imap4d_status (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc < 4)
return TOO_FEW;
if (argv[3][0] != '(' || argv[argc-1][strlen(argv[argc-1])-1] != ')')
return util_finish (argc, argv, RESP_BAD, NULL, "Invalid args");
return NOT_IMPL;
}
......
......@@ -18,12 +18,11 @@
#include "imap4d.h"
/*
*
* Now you're messing with a sumbitch
*/
int
imap4d_store (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
return NOT_IMPL;
}
......
......@@ -24,6 +24,9 @@
int
imap4d_subscribe (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 3)
return TOO_MANY;
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -18,12 +18,12 @@
#include "imap4d.h"
/*
*
* see comment in store.c, raise to the nth power
* this is really going to sux0r (maybe)
*/
int
imap4d_uid (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
return NOT_IMPL;
}
......
......@@ -24,6 +24,9 @@
int
imap4d_unsubscribe (int argc, char **argv)
{
util_out (argv[0], TAG_NONE, "BAD %s Command not implemented", argv[1]);
return util_finish (argc, argv, RESP_BAD, "Command not implemented");
if (argc > 3)
return TOO_MANY;
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
}
......
......@@ -45,10 +45,11 @@ util_out (char *seq, int tag, char *f, ...)
}
int
util_finish (int argc, char **argv, int resp, char *f, ...)
util_finish (int argc, char **argv, int resp, char *rc, char *f, ...)
{
char *buf = NULL, *buf2 = NULL, *code = NULL;
int len = 0;
struct imap4d_command *cmd = util_getcommand (argv[1]);
va_list ap;
va_start (ap, f);
......@@ -56,18 +57,23 @@ util_finish (int argc, char **argv, int resp, char *f, ...)
{
case RESP_OK:
code = strdup ("OK");
/* set state (cmd->success); */
break;
case RESP_BAD:
code = strdup ("BAD");
break;
case RESP_NO:
code = strdup ("NO");
/* set state (cmd->failure); */
break;
default:
code = strdup ("X-BUG");
}
vasprintf (&buf, f, ap);
if (rc != NULL)
len = asprintf (&buf, "%s %s %s %s %s\r\n", argv[0],code,rc,argv[1],buf);
else
len = asprintf (&buf2, "%s %s %s %s\r\n", argv[0], code, argv[1], buf);
write (ofile, buf2, len);
......@@ -75,6 +81,8 @@ util_finish (int argc, char **argv, int resp, char *f, ...)
free (buf);
free (buf2);
free (code);
free (rc);
argcv_free (argc, argv);
return resp;
}
......@@ -123,65 +131,35 @@ util_getline (void)
int
util_do_command (char *cmd)
{
if (cmd == NULL)
return 0;
else
{
int argc = 0, status = 0, i = 0, len;
int argc = 0, i = 0;
char **argv = NULL;
struct imap4d_command *command = NULL;
if (cmd == NULL)
return 0;
if (argcv_get (cmd, &argc, &argv) != 0)
{
argcv_free (argc, argv);
return 1;
}
util_start (argv[0]);
if (argc < 2)
{
util_finish (argc, argv, RESP_BAD,
"Client did not send space after tag");
argcv_free (argc, argv);
return 1;
}
return util_finish (argc, argv, RESP_BAD, NULL, "No space after tag");
len = strlen (argv[1]);
for (i=0; i < len; i++)
argv[1][i] = tolower (argv[1][i]);
for (i=0; command == NULL && imap4d_command_table[i].name != 0; i++)
{
if (strlen (imap4d_command_table[i].name) == len &&
!strcmp (imap4d_command_table[i].name, argv[1]))
command = &imap4d_command_table[i];
}
command = util_getcommand (argv[1]);
for (i=0; i < len; i++)
for (i=0; i < strlen (argv[1]); i++)
argv[1][i] = toupper (argv[1][i]);
if (command == NULL)
{
util_finish (argc, argv, RESP_BAD, "Invalid command");
argcv_free (argc, argv);
return 1;
}
return util_finish (argc, argv, RESP_BAD, NULL, "Invalid command");
else if (! (command->states & util_getstate ()))
{
util_finish (argc, argv, RESP_BAD, "Incorrect state");
argcv_free (argc, argv);
return 1;
}
else
{
status = command->func (argc, argv);
argcv_free (argc, argv);
return status;
}
}
return 1;
return util_finish (argc, argv, RESP_BAD, NULL, "Incorrect state");
return command->func (argc, argv);
}
int
......@@ -195,3 +173,17 @@ util_getstate (void)
{
return STATE_NONAUTH;
}
struct imap4d_command *
util_getcommand (char *cmd)
{
int i = 0, len = strlen (cmd);
for (i = 0; imap4d_command_table[i].name != 0; i++)
{
if (strlen (imap4d_command_table[i].name) == len &&
!strcasecmp (imap4d_command_table[i].name, cmd))
return &imap4d_command_table[i];
}
return NULL;
}
......