aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap/imap.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/imap/imap.c')
-rw-r--r--camel/providers/imap/imap.c835
1 files changed, 0 insertions, 835 deletions
diff --git a/camel/providers/imap/imap.c b/camel/providers/imap/imap.c
deleted file mode 100644
index 3a4109ed47..0000000000
--- a/camel/providers/imap/imap.c
+++ /dev/null
@@ -1,835 +0,0 @@
-/* Spruce
- * Copyright (C) 1999-2000 Jeffrey Stedfast
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "imap.h"
-
-#define IMAP_LOGGING
-
-/* this is used in the tag before each command */
-static guint32 imap_commands = 0;
-
-extern gint timeout;
-extern GList *mime_parts;
-
-
-gint imap_ok (gint tag, gchar *line)
-{
- /* returns 1 if <tag> OK was found */
- gchar find[64];
- gint ret;
-
- g_snprintf(find, sizeof(find)-1, "A%.5d OK", tag);
-
- ret = find_string (line, find);
-
- if (ret < 0)
- return 0;
-
- return 1;
-}
-
-gint imap_login_cram_md5 (gint socket, gchar *username, gchar *password)
-{
- /* Log in to server using CRAM-MD5 keyed hash. */
- gchar buffer[512];
- gchar *retstr;
- gint pos;
-
- if (username == NULL || password == NULL)
- return ERROR;
-
- memset(buffer, 0, sizeof(buffer));
- if (recvline(socket, buffer, sizeof(buffer)-1) < 0)
- return ERROR; /* Fetch the OK line from the server */
-
- if (find_string(buffer, "OK") == -1)
- return ERROR;
-
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d AUTHENTICATE CRAM-MD5\r\n", imap_commands);
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- return ERROR;
-
- memset(buffer, 0, sizeof(buffer));
- if (recvline(socket, buffer, sizeof(buffer)-1) < 0)
- return ERROR;
-
- pos = find_string(buffer, "\r\n");
- if (pos != -1)
- buffer[pos] = '\0';
- retstr = cram_md5(username, password, buffer);
-
- if (retstr[strlen(retstr)-1] == '\n')
- retstr[strlen(retstr)-1] = '\0';
-
- g_snprintf(buffer, sizeof(buffer)-1, "%s\r\n", retstr);
- g_free(retstr);
-
- if (send (socket, buffer, strlen(buffer), 0) < 0)
- return ERROR;
-
- if (recvline(socket, buffer, sizeof(buffer)-1) < 0)
- return ERROR;
-
- if (!imap_ok(imap_commands, buffer))
- return ERROR;
-
- imap_commands++;
-
- return SUCCESS;
-}
-
-gint imap_login (gint socket, gchar *username, gchar *password)
-{
- /* this logs us in to the server */
- gchar buffer[512];
- gchar temp[64];
-
- if (username == NULL || password == NULL)
- return ERROR;
-
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d LOGIN \"%s\" \"%s\"\r\n", imap_commands, username, password);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send (socket, buffer, strlen(buffer), 0) < 0)
- {
- return ERROR;
- }
-
- g_snprintf(temp, sizeof(temp)-1, "A%.5d", imap_commands);
-
- memset(buffer, 0, sizeof(buffer));
- recvline_timeo(socket, buffer, sizeof(buffer)-1, timeout);
- while (!strstr(buffer, temp))
- {
- memset(buffer, 0, sizeof(buffer));
- recvline_timeo(socket, buffer, sizeof(buffer)-1, timeout);
- }
-
- if (!imap_ok(imap_commands, buffer))
- return ERROR;
-
- imap_commands++;
-
- return SUCCESS;
-}
-
-GList *imap_list (gint socket, gchar *namespace)
-{
- /* this gets the names of all the mailboxes */
- gchar buffer[512];
- gchar flags[256];
- gchar temp[64], *ptr = NULL, *flagptr = NULL;
- gchar slashdot = '\0';
- GList *list = NULL;
- gint ret, size = 0, flaglen = 0;
-
- if (namespace && *namespace)
- {
- if (*namespace && namespace[strlen(namespace)-1] != '/' && namespace[strlen(namespace)-1] != '.')
- slashdot = '/';
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d LIST \"\" %s%c*\r\n", imap_commands, namespace, slashdot);
- }
- else
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d LIST \"\" INBOX.*\r\n", imap_commands);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- {
- return NULL;
- }
-
- do
- {
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(socket, buffer, sizeof(buffer)-1);
- if (ret > 0)
- {
-#ifdef IMAP_LOGGING
- fprintf(stderr, "received: %s", buffer);
-#endif
- if (buffer[0] == '*')
- {
- strip(buffer, '\r');
- strip(buffer, '\n');
-
- /* skip ahead to the flag section */
- ptr = strstr(buffer, "(");
-
- /* find the end of the flags section */
- flagptr = ptr + 1;
- ptr = strstr(ptr, ")") + 1;
-
- /* eventually we will need to parse this */
- memset(flags, 0, sizeof(flags));
- flaglen = (gint)(ptr - flagptr) - 1;
- size = sizeof(flags);
- strncpy(flags, flagptr, flaglen > size ? size : flaglen);
- if (!strstrcase(flags, "\\NoSelect")) /* is this a selectable mailbox? */
- {
- /* skip the reference name */
- ptr += imap_get_string (ptr, temp, sizeof(temp)-1, "");
-
- /* the rest of the return string is fair play... */
- g_strstrip(ptr); /* trim off any extra white space */
- unquote(ptr); /* unquote the mailbox name if it is quoted */
- if (slashdot)
- strcut(ptr, 0, strlen(namespace)+1); /* cut out the namespace and the '/' */
- else
- strcut(ptr, 0, strlen(namespace)); /* cut out the namespace */
-
-
- list = g_list_append (list, g_strdup(ptr));
- }
- }
- else
- break;
- }
- } while (ret > 0);
-
- imap_commands++;
-
- return list;
-}
-
-gint imap_select_mailbox (gint socket, gchar *mailbox, gchar *namespace)
-{
- /* selects a mailbox, returns the number of messages in that mailbox
- * or -1 on error */
- gchar *cmdbuf, buffer[512], temp[64], *index, mesgs[16];
- gchar slashdot = '\0';
- gint ret, i;
-
- if (mailbox == NULL)
- return ERROR;
-
- if (namespace && strcmp(mailbox, "INBOX"))
- {
- if (*namespace && namespace[strlen(namespace)-1] != '/' && namespace[strlen(namespace)-1] != '.')
- slashdot = '/';
-
- cmdbuf = g_strdup_printf("A%.5d SELECT %s%c%s\r\n", imap_commands, namespace, slashdot, mailbox);
- }
- else
- cmdbuf = g_strdup_printf("A%.5d SELECT %s\r\n", imap_commands, mailbox);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", cmdbuf);
-#endif
-
- if (send(socket, cmdbuf, strlen(cmdbuf), 0) < 0)
- {
- g_free(cmdbuf);
- return -1;
- }
- g_free(cmdbuf);
-
- g_snprintf(temp, sizeof(temp)-1, "A%.5d", imap_commands);
-
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(socket, buffer, sizeof(buffer)-1);
- while (ret > 0)
- {
-#ifdef IMAP_LOGGING
- fprintf(stderr, "received: %s", buffer);
-#endif
- if (strstr(buffer, temp))
- break;
- if (buffer[0] == '*')
- {
- if (strstr(buffer, "EXISTS"))
- {
- index = buffer;
- while (*index != ' ')
- index++;
- index++;
-
- i = 0;
- memset(mesgs, 0, sizeof(mesgs));
- while (*index != ' ' && i < sizeof(mesgs)-1)
- {
- mesgs[i] = *index;
- index++;
- i++;
- }
- }
- }
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(socket, buffer, sizeof(buffer)-1);
- }
-
- if (!imap_ok(imap_commands, buffer))
- return -1;
-
- imap_commands++;
-
- return atoi(mesgs);
-}
-
-gint imap_logout (gint socket)
-{
- /* logs out */
- gchar buffer[256];
-
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d LOGOUT\r\n", imap_commands);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- {
- return ERROR;
- }
-
- return SUCCESS;
-}
-
-gint imap_mailbox_create (gint socket, gchar *mailbox)
-{
- /* creates a new mailbox */
- gchar buffer[256];
-
- if (mailbox == NULL)
- return ERROR;
-
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d CREATE %s\r\n", imap_commands, mailbox);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- {
- return ERROR;
- }
-
- memset(buffer, 0, sizeof(buffer));
- if (recvline(socket, buffer, sizeof(buffer)-1) < 0 || !imap_ok(imap_commands, buffer))
- {
- return ERROR;
- }
-
- imap_commands++;
-
- return SUCCESS;
-}
-
-gint imap_mailbox_delete (gint socket, gchar *mailbox)
-{
- /* deletes a mailbox */
- gchar buffer[256];
-
- if (mailbox == NULL)
- return ERROR;
-
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d DELETE %s\r\n", imap_commands, mailbox);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- {
- return ERROR;
- }
-
- memset(buffer, 0, sizeof(buffer));
- if (recvline(socket, buffer, sizeof(buffer)-1) < 0 ||
- !imap_ok(imap_commands, buffer))
- {
- return ERROR;
- }
-
- imap_commands++;
-
- return SUCCESS;
-}
-
-/* fetches the specified part of a message, which can be alot of
- * if you use peek the \Seen flag is not set */
-gchar *imap_fetch (gint socket, gint mesgnum, gchar *part, gint *seen)
-{
- /* fetches the specified part of the mesg. */
- gchar *mesg = NULL;
- gchar buffer[512], *index;
- gchar flags[128], size[16], temp[64];
- gint i, n, msgsize = 1000;
-
- if (mesgnum < 0)
- return (gchar *)NULL;
-
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d FETCH %d (FLAGS %s)\r\n", imap_commands, mesgnum, part);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- {
- return (gchar *)NULL;
- }
-
-
- memset(buffer, 0, sizeof(buffer));
- n = recvline(socket, buffer, sizeof(buffer)-1);
-
- if (buffer[0] != '*' && imap_ok(imap_commands, buffer))
- {
- memset(buffer, 0, sizeof(buffer));
- n = recvline(socket, buffer, sizeof(buffer)-1);
- }
-
- if (buffer[0] == '*')
- /*if (imap_ok(imap_commands, buffer))*/
- {
- index = strstrcase(buffer, "FLAGS");
- if (index == NULL) /* hmm */
- {
- fprintf(stderr, _("IMAP server replied using unknown tokens.\n"));
- return (gchar *)NULL;
- }
- else
- {
-#ifdef IMAP_LOGGING
- fprintf(stderr, "received: %s", buffer);
-#endif
- /* skip to the FLAGS token */
- for ( ; *index && *index != '('; index++);
- index++;
-
- i = 0;
- memset(flags, 0, sizeof(flags));
- while (*index != ')' && i < sizeof(flags)-1)
- {
- flags[i] = *index;
- index++;
- i++;
- }
- flags[i] = '\0';
-
- /* skip to the next significant token */
- for (index++; *index && *index != '{'; index++);
- index++;
-
- i = 0;
- memset(size, 0, sizeof(size));
- while (*index != '}' && i < sizeof(size)-1)
- {
- size[i] = *index;
- index++;
- i++;
- }
- size[i] = '\0';
- msgsize = atoi(size);
- }
- }
- else
- {
- g_snprintf(temp, sizeof(temp)-1, "A%.5d", imap_commands);
- if (strstr(buffer, temp)) /* this means there's no such message */
- {
- fprintf(stderr, _("IMAP responded with \"no such message\".\n"));
- return (gchar *)NULL;
- }
- }
-
-
- mesg = g_malloc0(msgsize + 50); /* just to be safe */
- n = recvline(socket, buffer, sizeof(buffer)-1);
-
- while (!(n <= 0) && !imap_ok(imap_commands, buffer))
- {
- strip(buffer, '\r'); /* strip all the \r's */
- strcat(mesg, buffer);
- memset(buffer, 0, sizeof(buffer));
- n = recvline(socket, buffer, sizeof(buffer)-1);
- }
-
- if (mesg)
- mesg[strlen(mesg)-3] = '\0'; /* strip the ending ) */
-
- if (seen != NULL)
- {
- if (strstrcase(flags, "\\Seen"))
- *seen = 1;
- else
- *seen = 0;
- }
-
- imap_commands++;
-
- return (gchar*)mesg;
-}
-
-gboolean imap_delete(const ImapAccount_t *imap, GList *sorted)
-{
- GList *p = sorted;
- gchar buffer[256];
- gchar temp[16];
- gint ret;
-
- do
- {
- gint id = GPOINTER_TO_INT(p->data);
- g_snprintf(buffer, sizeof(buffer)-1, "A%.5d STORE %d +FLAGS (\\Deleted)\r\n", imap_commands, id);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
- if (send(imap->socket, buffer, strlen(buffer), 0) < 0)
- {
- return FALSE;
- }
- g_snprintf(temp, sizeof(temp)-1, "A%.5d", imap_commands);
-
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(imap->socket, buffer, sizeof(buffer)-1);
- while (ret > 0)
- {
- if (find_string(buffer, temp) >= 0)
- break;
-
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(imap->socket, buffer, sizeof(buffer)-1);
- }
-
- if (!imap_ok(imap_commands, buffer))
- {
- return FALSE;
- }
- imap_commands++;
- } while ((p = g_list_next(p)));
-
- g_snprintf(buffer, 255, "A%.5d EXPUNGE\r\n", imap_commands);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
- if (send(imap->socket, buffer, strlen(buffer), 0) < 0)
- {
- return FALSE;
- }
-
- g_snprintf (temp, 15, "A%.5d", imap_commands);
-
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(imap->socket, buffer, sizeof(buffer)-1);
- while (ret > 0)
- {
- if (find_string(buffer, temp) >= 0)
- break;
-
- memset(buffer, 0, sizeof(buffer));
- ret = recvline(imap->socket, buffer, sizeof(buffer)-1);
- }
-
- if (!imap_ok(imap_commands, buffer))
- {
- return FALSE;
- }
-
- imap_commands++;
-
- return TRUE;
-}
-
-gint imap_connect (Server *server)
-{
- /* connects to the server and returns the socket or -1 on error */
- gchar buffer[512];
- gint sock;
-
- if (!Resolve(server))
- return -1;
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0)
- return -1;
-
- server->sin.sin_family = AF_INET;
- server->sin.sin_port = htons(server->port);
-
-#ifdef IMAP_LOGGING
- fprintf(stderr, _("Connecting to IMAP server (%s)..."), server->ip);
-#endif
- if (connect_timeo(sock, (struct sockaddr*)&server->sin, sizeof(server->sin), timeout) < 0)
- {
- fprintf(stderr, _("failed.\n"));
- close(sock);
- return -1;
- }
- fprintf(stderr, _("success.\n"));
-
- {
- /* read the connect responce */
- memset(buffer, 0, sizeof(buffer));
- recvline_timeo(sock, buffer, sizeof(buffer)-1, timeout);
- }
-
- return sock;
-}
-
-gint imap_add_part(gchar *c)
-{
- gchar name[64], value[64];
- gchar temp[64];
- gchar *start = c;
- struct mime_part *part;
-
- part = g_malloc0(sizeof(struct mime_part));
-
- c += imap_get_string (c, part->type, sizeof(part->type)-1, "text");
- c += imap_get_string (c, part->subtype, sizeof(part->subtype)-1, "plain");
-
- /* seek to the beginning of the parameter... */
- for ( ; *c && *c == ' '; c++);
-
- if (*c)
- {
- gchar *p = part->parameter;
- if (*c == '(')
- {
- c++;
- while (*c && *c != ')')
- {
- c += imap_get_string (c, name, sizeof(name)-1, "");
- c += imap_get_string (c, value, sizeof(value)-1, "");
- /* don't buffer overrun */
- g_snprintf(p, sizeof(part->parameter)-1, "%s=\"%s\"; ", name, value);
- p += strlen(p);
-
- while (*c && *c == ' ') /* skip any spaces */
- c++;
- }
- }
- else
- {
- c += imap_get_string (c, name, sizeof(name)-1, "");
- strcpy(value, name);
- *p++ = '\0';
- }
-
- c++; /* skip over the ')' belonging to the parameter values */
- if (*c)
- {
- /* ignore id and description */
- c += imap_get_string (c, temp, sizeof(temp)-1, "");
- c += imap_get_string (c, temp, sizeof(temp)-1, "");
-
- /* encoding */
- c += imap_get_string (c, part->encoding, sizeof(part->encoding)-1, "");
-
- /* size */
- c += imap_get_number (c, &part->len);
-
- /* skip the optional info */
- c += imap_skip_section(c);
-
- part->pos = 0; /* isn't useful in imap */
-#ifdef IMAP_LOGGING
- fprintf(stderr, "type = %s/%s\n", part->type, part->subtype);
- fprintf(stderr, "encoding = %s\n", part->encoding);
- fprintf(stderr, "param = %s\n", part->parameter);
-#endif
- mime_parts = g_list_append (mime_parts, part);
-
- return (c - start);
- }
- }
- return -1;
-}
-
-gint imap_parts (gint socket, gint mesg_num)
-{
- GList *tmp;
- gchar *buffer = NULL, *c;
- gint res = 1, cnt;
-
- tmp = mime_parts;
- while (tmp != NULL)
- {
- g_free(tmp->data);
- tmp = tmp->next;
- }
-
- if (mime_parts != NULL)
- {
- g_list_free(mime_parts);
- mime_parts = NULL;
- }
-
- buffer = g_malloc0(sizeof(gchar)*2048);
-
- g_snprintf(buffer, 2047, "A%.5d FETCH %d (BODYSTRUCTURE)\r\n", imap_commands, mesg_num);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "%s", buffer);
-#endif
-
- if (send(socket, buffer, strlen(buffer), 0) < 0)
- {
- g_free(buffer);
- return 0;
- }
-
- /* get the structure of the body */
- memset (buffer, 0, sizeof(gchar)*2048);
- recvline (socket, buffer, sizeof(gchar)*2048);
-#ifdef IMAP_LOGGING
- fprintf(stderr, "received: %s", buffer);
-#endif
-
- c = buffer;
- /* skip to the BODYSTRUCTURE */
- c = strstr(c, "BODYSTRUCTURE");
- if (c == NULL)
- return 0;
-
- c += strlen("BODYSTRUCTURE");
- if (*c)
- {
- /* looks good so far, skip to the parts */
- for ( ; *c && *c != '('; c++);
-
- if (*c && *(c+1) == '(')
- {
- c++;
-#ifdef IMAP_LOGGING
- fprintf(stderr, "message is multipart\n");
-#endif
- /* multipart */
- while (*c == '(')
- {
- cnt = imap_skip_section(c);
- if (cnt > 1)
- {
- c[cnt-1] = '\0';
- cnt = imap_add_part(c);
- if (cnt == -1)
- {
- res = 0;
- break;
- }
- c += cnt;
- }
- else
- {
- res = 0;
- break;
- }
- /* skip to the next mime part */
- for ( ; *c && *c == ' '; c++);
- }
- }
- else
- if (*c)
- {
- /* one part */
- cnt = imap_add_part(c);
- res = res != -1;
- }
- /* just forget the rest, who cares?? */
- }
-
- g_free(buffer);
-
- return res;
-}
-
-gint imap_get_string (gchar *index, gchar *dest, gint destlen, gchar *def)
-{
- /* gets a string ("data" or NIL) , if NIL it copies def instead */
- gint i;
- gchar *start = index;
-
- while (*index && *index == ' ') /* skip white space */
- index++;
-
- if (strncmp(index, "NIL", 3))
- {
- /* progress to the first quote (we should already be there but just in case) */
- while (*index && *index != '"')
- index++;
-
- index++;
-
- i = 0;
- while (*index && *index != '"')
- {
- if (i < destlen-1)
- {
- dest[i] = *index;
- i++;
- }
- index++;
- }
- dest[i] = '\0';
- }
- else
- {
- /* if there were no data we just copy def */
- index += 3;
- strncpy (dest, def, destlen);
- }
-
- return index - start + 1;
-}
-
-gint imap_get_number (gchar *index, gint *dest)
-{
- /* gets a number */
- gchar number[32];
- gchar *start = index;
- gint i;
-
- /* skip white space **/
- while (*index == ' ')
- index++;
-
- i = 0;
- while (*index != ' ' && i < sizeof(number)-1)
- {
- number[i] = *index;
- index++;
- i++;
- }
- number[i] = '\0';
-
- *dest = atoi(number);
-
- return index - start;
-}
-
-gint imap_skip_section(gchar *index)
-{
- gint depth = 1;
- gchar *start = index;
-
- while (depth != 0 && *index)
- {
- if (*index == '(')
- depth++;
- else if ( *index == ')' )
- depth--;
- index++;
- }
-
- return index - start;
-}
-