Commit 48b49232 48b492320e9b852dcdc7a637f6d7d9dfd1895019 by Alain Magloire

Ok, working from Jakob first draft, get things in

shape and ready.  The biggest thing will be the
awfull parsing done for FETCH/SEARCH etc ..
"This will be for another day" -- Scarlet O'hara
1 parent 8c2c480c
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,9 +22,7 @@
*/
int
imap4d_append (int argc, char **argv)
imap4d_append (struct imap4d_command *command, char *arg)
{
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not implemented");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,7 +22,7 @@
*/
int
imap4d_authenticate (int argc, char **argv)
imap4d_authenticate (struct imap4d_command *command, char *arg)
{
return util_finish (argc, argv, RESP_NO, NULL, "Type not supported");
return util_finish (command, RESP_NO, "Command not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -18,10 +18,8 @@
#include "imap4d.h"
int
imap4d_capability (int argc, char **argv)
imap4d_capability (struct imap4d_command *command, char *arg)
{
if (argc > 2)
return TOO_MANY;
util_out (argv[0], TAG_NONE, "CAPABILITY IMAP4rev1");
return util_finish (argc, argv, RESP_OK, NULL, "Completed");
util_out (RESP_NONE, "CAPABILITY IMAP4rev1");
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -19,12 +19,12 @@
/*
* 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.
*/
int
imap4d_check (int argc, char **argv)
imap4d_check (struct imap4d_command *command, char *arg)
{
if (argc > 2)
return TOO_MANY;
return util_finish (argc, argc, RESP_OK, NULL, "Completed");
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -18,13 +18,21 @@
#include "imap4d.h"
/*
*
*/
int
imap4d_close (int argc, char **argv)
imap4d_close (struct imap4d_command *command, char *arg)
{
if (argc > 2)
return TOO_MANY;
return NOT_IMPL;
/* FIXME: Check args. */
/* FIXME: Check state and if they selected. */
/* FIXME: state = AUTHENTICATE. */
/* FIXME: Check and report errors. */
mailbox_expunge (mbox);
mailbox_close (mbox);
mailbox_destroy (&mbox);
/* FIXME: state = Not selected. */
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -17,30 +17,31 @@
#include "imap4d.h"
const struct imap4d_command imap4d_command_table [] = {
{ "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 },
struct imap4d_command imap4d_command_table [] =
{
{ "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}
};
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_copy (int argc, char **argv)
imap4d_copy (struct imap4d_command *command, char *arg)
{
if (argc > 4)
return TOO_MANY;
else if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Command not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_create (int argc, char **argv)
imap4d_create (struct imap4d_command *command, char *arg)
{
if (argc > 3)
return TOO_MANY;
else if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Command not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_delete (int argc, char **argv)
imap4d_delete (struct imap4d_command *command, char *arg)
{
if (argc > 3)
return TOO_MANY;
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Command not supported");;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,7 +22,7 @@
*/
int
imap4d_examine (int argc, char **argv)
imap4d_examine (struct imap4d_command *command, char *arg)
{
return NOT_IMPL;
return imap4d_select0 (command, arg, MU_STREAM_READ);
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,9 +22,14 @@
*/
int
imap4d_expunge (int argc, char **argv)
imap4d_expunge (struct imap4d_command *command, char *arg)
{
if (argc > 2)
return TOO_MANY;
return NOT_IMPL;
char *sp;
if (util_getword (arg, &sp))
return util_finish (command, RESP_NO, "Too many args");
/* FIXME: Check state, check for errors. */
mailbox_expunge (mbox);
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,10 +22,17 @@
*/
int
imap4d_fetch (int argc, char **argv)
imap4d_fetch (struct imap4d_command *command, char *arg)
{
if (argc < 4)
return TOO_FEW;
char *sp = NULL;
char *message_set;
char *item;
message_set = util_getword (arg, &sp);
item = util_getword (NULL, &sp);
if (!message_set || !item)
return util_finish (command, RESP_BAD, "Too few args");
/* check for paren list */
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -17,8 +17,12 @@
#include "imap4d.h"
int ifile;
int ofile;
int *ifile;
FILE *ofile;
unsigned int timeout = 1800; /* RFC2060: 30 minutes, if enable. */
mailbox_t mbox;
static int imap4_mainloop __P ((int, int));
int
main (int argc, char **argv)
......@@ -26,22 +30,41 @@ main (int argc, char **argv)
chdir ("/");
openlog ("imap4d", LOG_PID, LOG_MAIL);
/* for each incoming connection */
/* Register the desire formats. We only need Mbox mail format. */
{
char *remote_host = "";
ifile = fileno (stdin);
ofile = fileno (stdout);
syslog (LOG_INFO, "Incoming connection from %s", remote_host);
util_out (NULL, TAG_NONE, "IMAP4rev1 GNU " PACKAGE " " VERSION);
while (1)
{
char *cmd = util_getline ();
/* check for updates */
util_do_command (cmd);
free (cmd);
}
list_t bookie;
registrar_get_list (&bookie);
list_append (bookie, path_record);
}
/* FIXME: Incomplete, make it work for standalone, see pop3d. */
imap4_mainloop (fileno (stdin), fileno (stdout));
return 0;
}
static int
imap4_mainloop (int infile, int outfile)
{
const char *remote_host = "";
ofile = fdopen (outfile, "w");
if (ofile == NULL)
util_quit (1);
/* FIXME: Retreive hostname with getpeername() and log. */
syslog (LOG_INFO, "Incoming connection from %s", remote_host);
/* Greetings. */
util_out (RESP_OK, "IMAP4rev1 GNU " PACKAGE " " VERSION);
fflush (ofile);
while (1)
{
char *cmd = imap4d_readline (infile);
/* check for updates */
util_do_command (cmd);
free (cmd);
fflush (ofile);
}
closelog ();
return 0;
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,6 +22,12 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -36,14 +42,11 @@
#include <sys/time.h>
#include <sys/stat.h>
#include <argp.h>
#include <mailutils/mailbox.h>
#include <mailutils/message.h>
#include <mailutils/header.h>
#include <mailutils/body.h>
#include <argcv.h>
#include <mailutils/registrar.h>
#ifdef __cplusplus
extern "C" {
......@@ -57,72 +60,74 @@ extern "C" {
# endif
#endif /*__P */
/* Type definitions */
#ifndef Function
typedef int Function ();
#endif
struct imap4d_command {
char *name;
Function *func;
struct imap4d_command
{
const char *name;
int (*func) __P ((struct imap4d_command *, char *));
int states;
int success;
int failure;
char *tag;
};
/* Global variables and constants*/
#define STATE_NONE 1<<0
#define STATE_NONAUTH 1<<1
#define STATE_AUTH 1<<2
#define STATE_SEL 1<<3
#define STATE_LOGOUT 1<<4
#define STATE_NONE (1 << 0)
#define STATE_NONAUTH (1 << 1)
#define STATE_AUTH (1 << 2)
#define STATE_SEL (1 << 3)
#define STATE_LOGOUT (1 << 4)
#define STATE_ALL (STATE_NONE | STATE_NONAUTH | STATE_AUTH | STATE_SEL \
| STATE_LOGOUT)
#define TAG_NONE 0
#define TAG_SEQ 1
#define RESP_OK 0
#define RESP_BAD 1
#define RESP_NO 2
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));
int imap4d_logout __P ((int argc, char **argv));
int imap4d_authenticate __P ((int argc, char **argv));
int imap4d_login __P ((int argc, char **argv));
int imap4d_select __P ((int argc, char **argv));
int imap4d_examine __P ((int argc, char **argv));
int imap4d_create __P ((int argc, char **argv));
int imap4d_delete __P ((int argc, char **argv));
int imap4d_rename __P ((int argc, char **argv));
int imap4d_subscribe __P ((int argc, char **argv));
int imap4d_unsubscribe __P ((int argc, char **argv));
int imap4d_list __P ((int argc, char **argv));
int imap4d_lsub __P ((int argc, char **argv));
int imap4d_status __P ((int argc, char **argv));
int imap4d_append __P ((int argc, char **argv));
int imap4d_check __P ((int argc, char **argv));
int imap4d_close __P ((int argc, char **argv));
int imap4d_expunge __P ((int argc, char **argv));
int imap4d_search __P ((int argc, char **argv));
int imap4d_fetch __P ((int argc, char **argv));
int imap4d_store __P ((int argc, char **argv));
int imap4d_copy __P ((int argc, char **argv));
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 *r, char *f, ...));
#define RESP_BYE 3
#define RESP_NONE 4
extern struct imap4d_command imap4d_command_table[];
extern FILE *ofile;
extern unsigned int timeout;
extern mailbox_t mbox;
extern unsigned int state;
/* Imap4 commands */
int imap4d_capability __P ((struct imap4d_command *, char *));
int imap4d_noop __P ((struct imap4d_command *, char *));
int imap4d_logout __P ((struct imap4d_command *, char *));
int imap4d_authenticate __P ((struct imap4d_command *, char *));
int imap4d_login __P ((struct imap4d_command *, char *));
int imap4d_select __P ((struct imap4d_command *, char *));
int imap4d_select0 __P ((struct imap4d_command *, char *, int));
int imap4d_examine __P ((struct imap4d_command *, char *));
int imap4d_create __P ((struct imap4d_command *, char *));
int imap4d_delete __P ((struct imap4d_command *, char *));
int imap4d_rename __P ((struct imap4d_command *, char *));
int imap4d_subscribe __P ((struct imap4d_command *, char *));
int imap4d_unsubscribe __P ((struct imap4d_command *, char *));
int imap4d_list __P ((struct imap4d_command *, char *));
int imap4d_lsub __P ((struct imap4d_command *, char *));
int imap4d_status __P ((struct imap4d_command *, char *));
int imap4d_append __P ((struct imap4d_command *, char *));
int imap4d_check __P ((struct imap4d_command *, char *));
int imap4d_close __P ((struct imap4d_command *, char *));
int imap4d_expunge __P ((struct imap4d_command *, char *));
int imap4d_search __P ((struct imap4d_command *, char *));
int imap4d_fetch __P ((struct imap4d_command *, char *));
int imap4d_store __P ((struct imap4d_command *, char *));
int imap4d_copy __P ((struct imap4d_command *, char *));
int imap4d_uid __P ((struct imap4d_command *, char *));
/* Helper functions. */
int util_out __P ((int rc, const char *f, ...));
int util_start __P ((char *tag));
int util_finish __P ((struct imap4d_command *, int rc, const char *f, ...));
int util_getstate __P ((void));
int util_do_command __P ((char *prompt));
char *imap4d_readline __P ((int fd));
void util_quit __P ((int));
char *util_getword __P ((char *s, char **save_ptr));
struct imap4d_command *util_getcommand __P ((char *cmd));
#ifdef __cplusplus
......@@ -130,4 +135,3 @@ struct imap4d_command *util_getcommand __P ((char *cmd));
#endif
#endif /* _IMAP4D_H */
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_list (int argc, char **argv)
imap4d_list (struct imap4d_command *command, char *arg)
{
if (argc > 4)
return TOO_MANY;
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -18,17 +18,37 @@
#include "imap4d.h"
/*
* argv[2] == username
* argv[3] == password
* this should support PAM, shadow, and normal password
* FIXME: this should support PAM, shadow, and normal password
*/
int
imap4d_login (int argc, char **argv)
imap4d_login (struct imap4d_command *command, char *arg)
{
if (argc > 4)
return TOO_MANY;
else if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
struct passwd *pw;
char *sp = NULL, *username, *pass;
username = util_getword (arg, &sp);
pass = util_getword (NULL, &sp);
if (username == NULL || 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");
pw = getpwnam (arg);
if (pw == NULL || pw->pw_uid < 1)
return util_finish (command, RESP_NO, "User name or passwd rejected");
if (strcmp (pw->pw_passwd, crypt (pass, pw->pw_passwd)))
{
#ifdef HAVE_SHADOW_H
struct spwd *spw;
spw = getspnam (arg);
if (spw == NULL || strcmp (spw->sp_pwdp, crypt (pass, spw->sp_pwdp)))
#endif /* HAVE_SHADOW_H */
return util_finish (command, RESP_NO, "User name or passwd rejected");
}
if (pw->pw_uid > 1)
setuid (pw->pw_uid);
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,15 @@
*/
int
imap4d_logout (int argc, char **argv)
imap4d_logout (struct imap4d_command *command, char *arg)
{
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);
char *sp;
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
util_out (RESP_BYE, "Logging out");
util_finish (command, RESP_OK, "Completed");
mailbox_close (mbox);
mailbox_destroy (&mbox);
util_quit (0);
return 0;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_lsub (int argc, char **argv)
imap4d_lsub (struct imap4d_command *command, char *arg)
{
if (argc > 4)
return TOO_MANY;
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -17,10 +17,12 @@
#include "imap4d.h"
/* FIXME: Notify of new messages. */
int
imap4d_noop (int argc, char **argv)
imap4d_noop (struct imap4d_command *command, char *arg)
{
if (argc > 2)
return TOO_MANY;
return util_finish (argc, argv, RESP_OK, NULL, "Completed");
char *sp;
if (util_getword (arg, &sp))
return util_finish (command, RESP_BAD, "Too many args");
return util_finish (command, RESP_OK, "Completed");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_rename (int argc, char **argv)
imap4d_rename (struct imap4d_command *command, char *arg)
{
if (argc > 4)
return TOO_MANY;
if (argc < 4)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not Supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -19,12 +19,12 @@
/*
* This will be a royal pain in the arse to implement
* Alain: True, but the new lib mailbox should coming handy with
* some sort of query interface.
*/
int
imap4d_search (int argc, char **argv)
imap4d_search (struct imap4d_command *command, char *arg)
{
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -19,26 +19,57 @@
/*
* argv[2] == mailbox
* this needs to share code with EXAMINE
*/
int
imap4d_select (int argc, char **argv)
imap4d_select (struct imap4d_command *command, char *arg)
{
if (argc > 3)
return TOO_MANY;
else if (argc < 3)
return TOO_FEW;
return imap4d_select0 (command, arg, MU_STREAM_RDWR);
}
/* This code is share with EXAMINE. */
int
imap4d_select0 (struct imap4d_command *command, char *arg, int flags)
{
char *mailbox_name, *sp = NULL;
struct passwd *pw;
/* close previous mailbox */
if ( /* open mailbox (argv[2]) == */ 0)
/* FIXME: Check state. */
mailbox_name = util_getword (arg, &sp);
if (mailbox_name == NULL)
return util_finish (command, RESP_BAD, "Too few arguments");
if (util_getword (NULL, &sp))
return util_finish (command, RESP_BAD, "Too many arguments");
if (mbox)
{
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");
mailbox_close (mbox);
mailbox_destroy (&mbox);
}
if (strcasecmp (mailbox_name, "INBOX") == 0)
{
pw = getpwuid (getuid());
if (pw)
mailbox_name = pw->pw_name;
}
if (mailbox_create_default (&mbox, mailbox_name) == 0
&& mailbox_open (mbox, flags) == 0)
{
const char *sflags = "\\Answered \\Flagged \\Deleted \\Seen \\Draft";
int num = 0, recent = 0, uid = 0;
mailbox_messages_count (mbox, &num);
mailbox_recent_count (mbox, &recent);
util_out (RESP_NONE, "%d EXISTS", num);
util_out (RESP_NONE, "%d RECENT", recent);
util_out (RESP_NONE, "FLAGS (%s)", sflags);
util_out (RESP_OK, "[UIDNEXT %d]", num + 1);
/*util_out (RESP_OK, "[UIDVALIDITY (%d)]", uid);*/
/*util_out (RESP_OK, "[PERMANENTFLAGS (%s)]", flags);*/
return util_finish (command, RESP_OK, "Complete");
}
return util_finish (argc, argv, RESP_NO, NULL, "Couldn't open %s", argv[2]);
return util_finish (command, RESP_NO, "Couldn't open %s", mailbox_name);
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,14 @@
*/
int
imap4d_status (int argc, char **argv)
imap4d_status (struct imap4d_command *command, char *arg)
{
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;
char *sp = NULL;
char *mailbox_name;
char *data;
mailbox_name = util_getword (arg, &sp);
data = util_getword (NULL, &sp);
if (!mailbox_name || !data)
return util_finish (command, RESP_BAD, "Too few args");
return util_finish (command, RESP_BAD, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,7 +22,7 @@
*/
int
imap4d_store (int argc, char **argv)
imap4d_store (struct imap4d_command *command, char *arg)
{
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_subscribe (int argc, char **argv)
imap4d_subscribe (struct imap4d_command *command, char *arg)
{
if (argc > 3)
return TOO_MANY;
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -23,7 +23,7 @@
*/
int
imap4d_uid (int argc, char **argv)
imap4d_uid (struct imap4d_command *command, char *arg)
{
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2001 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
......@@ -22,11 +22,7 @@
*/
int
imap4d_unsubscribe (int argc, char **argv)
imap4d_unsubscribe (struct imap4d_command *command, char *arg)
{
if (argc > 3)
return TOO_MANY;
if (argc < 3)
return TOO_FEW;
return NOT_IMPL;
return util_finish (command, RESP_NO, "Not supported");
}
......
......@@ -17,163 +17,165 @@
#include "imap4d.h"
extern int ifile;
extern int ofile;
static const char *
rc2string (int rc)
{
switch (rc)
{
case RESP_OK:
return "OK ";
case RESP_BAD:
return "BAD ";
case RESP_NO:
return "NO ";
case RESP_BYE:
return "BYE ";
}
return "";
}
/* FIXME: Some words are:
between double quotes, consider like one word.
between parenthesis, consider line one word. */
char *
util_getword (char *s, char **save)
{
static char *sp;
return strtok_r (s, " \r\n", ((save) ? save : &sp));
}
int
util_out (char *seq, int tag, char *f, ...)
util_out (int rc, const char *format, ...)
{
char *buf = NULL;
int len = 0;
va_list ap;
va_start (ap, f);
len = vasprintf (&buf, f, ap);
if (tag == TAG_SEQ)
{
write (ofile, seq, strlen (seq));
write (ofile, " ", 1);
}
else if (tag == TAG_NONE)
write (ofile, "* ", 2);
va_start (ap, format);
vasprintf (&buf, format, ap);
va_end (ap);
write (ofile, buf, len);
write (ofile, "\r\n", 2);
fprintf (ofile, "* %s%s\r\n", rc2string (rc), buf);
free (buf);
return 0;
}
int
util_finish (int argc, char **argv, int resp, char *rc, char *f, ...)
util_finish (struct imap4d_command *command, int rc, const char *format, ...)
{
char *buf = NULL, *buf2 = NULL, *code = NULL;
/* FIXME: No argc maybe 1, then it will sigsegv. */
/* struct imap4d_command *cmd = util_getcommand (argv[1]); */
int len = 0;
char *buf = NULL;
const char *resp;
va_list ap;
va_start (ap, f);
switch (resp)
{
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, (argc > 1) ? argv[1] : "", buf);
else
len = asprintf (&buf2, "%s %s %s %s\r\n",
argv[0], code, (argc > 1) ? argv[1] : "", buf);
write (ofile, buf2, len);
va_start (ap, format);
vasprintf (&buf, format, ap);
va_end(ap);
resp = rc2string (rc);
fprintf (ofile, "%s %s%s %s\r\n", command->tag, resp, command->name, buf);
free (buf);
free (buf2);
free (code);
free (rc);
argcv_free (argc, argv);
return resp;
return 0;
}
char *
util_getline (void)
imap4d_readline (int fd)
{
fd_set rfds;
struct timeval tv;
char buf[1024], *ret = NULL;
int fd = ifile, len = 0;
char buf[512], *ret = NULL;
int nread;
int available;
FD_ZERO (&rfds);
FD_SET (fd, &rfds);
tv.tv_sec = 30;
tv.tv_sec = timeout;
tv.tv_usec = 0;
memset (buf, '\0', 1024);
do
{
if (!select (fd + 1, &rfds, NULL, NULL, &tv))
return NULL;
else if (read (fd, buf, 1024) < 1)
exit (1); /* FIXME: dead socket */
else if (ret == NULL)
if (timeout > 0)
{
available = select (fd + 1, &rfds, NULL, NULL, &tv);
if (!available)
util_quit (1); /* FIXME: Timeout. */
}
nread = read (fd, buf, sizeof (buf) - 1);
if (nread < 1)
util_quit (1); /* FIXME: dead socket */
buf[nread] = '\0';
if (ret == NULL)
{
ret = malloc ((strlen (buf + 1) * sizeof (char)));
ret = malloc ((nread + 1) * sizeof (char));
strcpy (ret, buf);
}
else
{
ret = realloc (ret, (strlen (ret) + strlen (buf) + 1) *
sizeof (char));
ret = realloc (ret, (strlen (ret) + nread + 1) * sizeof (char));
strcat (ret, buf);
}
/* FIXME: handle literal strings here. */
}
while (strchr (buf, '\n') == NULL);
for (len = strlen (ret); len > 0; len--)
if (ret[len] == '\r' || ret[len] == '\n')
ret[len] = '\0';
return ret;
}
int
util_do_command (char *cmd)
util_do_command (char *prompt)
{
int argc = 0, i = 0;
char **argv = NULL;
struct imap4d_command *command = NULL;
char *sp = NULL, *tag, *cmd, *arg;
struct imap4d_command *command;
static struct imap4d_command nullcommand;
if (cmd == NULL)
return 0;
if (argcv_get (cmd, &argc, &argv) != 0)
tag = util_getword (prompt, &sp);
cmd = util_getword (NULL, &sp);
if (!tag)
{
argcv_free (argc, argv);
return 1;
nullcommand.name = "";
nullcommand.tag = (char *)"*";
return util_finish (&nullcommand, RESP_BAD, "Null command");
}
else if (!cmd)
{
nullcommand.name = "";
nullcommand.tag = tag;
return util_finish (&nullcommand, RESP_BAD, "Missing arguments");
}
util_start (argv[0]);
if (argc < 2)
return util_finish (argc, argv, RESP_BAD, NULL, "No space after tag");
command = util_getcommand (argv[1]);
for (i=0; i < strlen (argv[1]); i++)
argv[1][i] = toupper (argv[1][i]);
util_start (tag);
command = util_getcommand (cmd);
if (command == NULL)
return util_finish (argc, argv, RESP_BAD, NULL, "Invalid command");
else if (! (command->states & util_getstate ()))
return util_finish (argc, argv, RESP_BAD, NULL, "Incorrect state");
{
nullcommand.name = "";
nullcommand.tag = tag;
return util_finish (&nullcommand, RESP_BAD, "Invalid command");
}
return command->func (argc, argv);
command->tag = tag;
return command->func (command, sp);
}
/* FIXME: What is this for? */
int
util_start (char *seq)
util_start (char *tag)
{
(void)tag;
return 0;
}
/* FIXME: Incomplete send errmsg to syslog, see pop3d:pop3_abquit(). */
void
util_quit (int err)
{
exit (err);
}
/* FIXME: What is this for? */
int
util_getstate (void)
{
......@@ -183,7 +185,7 @@ util_getstate (void)
struct imap4d_command *
util_getcommand (char *cmd)
{
int i = 0, len = strlen (cmd);
size_t i, len = strlen (cmd);
for (i = 0; imap4d_command_table[i].name != 0; i++)
{
......