diff options
Diffstat (limited to 'camel/providers/imap/imap.c')
-rw-r--r-- | camel/providers/imap/imap.c | 835 |
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; -} - |