/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* 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 of the License, 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 "mutt.h"
#include "mutt_curses.h"
#include "mx.h"
#include "mailbox.h"
#include "globals.h"
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
/* Minimal support for IMAP 4rev1 */
#define IMAP_PORT 143
#define SEQLEN 5
/* number of entries in the hash table */
#define IMAP_CACHE_LEN 10
enum
{
IMAP_FATAL = 1,
IMAP_NEW_MAIL,
IMAP_EXPUNGE,
IMAP_BYE
};
typedef struct
{
int index;
char *path;
} IMAP_CACHE;
typedef struct
{
short status;
unsigned short sequence;
unsigned short newMailCount;
short xxx;
IMAP_CACHE cache[IMAP_CACHE_LEN];
} IMAP_DATA;
/* simple read buffering to speed things up. */
static int imap_readchar (int fd, char *c)
{
static char inbuf[LONG_STRING];
static int bufpos=0, available=0;
if (bufpos>=available)
{
available = read (fd, inbuf, sizeof(inbuf));
bufpos = 0;
if (available <= 0)
return available; /* returns 0 for EOF or -1 for other error */
}
*c = inbuf[bufpos];
bufpos++;
return 1;
}
static int imap_read_line (char *buf, size_t buflen, int fd)
{
char ch;
int i;
for (i = 0; i < buflen; i++)
{
if (imap_readchar (fd, &ch) != 1)
return (-1);
if (ch == '\n')
break;
buf[i] = ch;
}
buf[i-1] = 0;
return (i + 1);
}
static int imap_read_line_d (char *buf, size_t buflen, int fd)
{
int r = imap_read_line (buf, buflen, fd);
dprint (1,(debugfile,"imap_read_line_d():%s\n", buf));
return r;
}
static void imap_make_sequence (char *buf, size_t buflen, CONTEXT *ctx)
{
snprintf (buf, buflen, "a%04d", ((IMAP_DATA *) ctx->data)->sequence++);
}
static int imap_write (int fd, const char *buf)
{
dprint (1,(debugfile,"imap_write():%s", buf));
return (write (fd, buf, strlen (buf)));
}
static void imap_error (const char *where, const char *msg)
{
dprint (1, (debugfile, "imap_error(): unexpected response in %s: %s\n", where, msg));
}
/* date is of the form: DD-MMM-YYYY HH:MM:SS +ZZzz */
static time_t imap_parse_date (char *s)
{
struct tm t;
time_t tz;
t.tm_mday = (s[0] - '0') * 10 + (s[1] - '0');
s += 2;
if (*s != '-')
return 0;
s++;
t.tm_mon = mutt_check_month (s);
s += 3;
if (*s != '-')
return 0;
s++;
t.tm_year = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0') - 1900;
s += 4;
if (*s != ' ')
return 0;
s++;
/* time */
t.tm_hour = (s[0] - '0') * 10 + (s[1] - '0');
s += 2;
if (*s != ':')
return 0;
s++;
t.tm_min = (s[0] - '0') * 10 + (s[1] - '0');
s += 2