#include <sys/socket.h>
#endif
#include <fcntl.h>
+#ifndef G_OS_WIN32
#include <sys/mman.h>
#include <sys/wait.h>
-
+#endif
#include <gtk/gtk.h>
#include <log.h>
#include "etpan-thread-manager.h"
return TRUE;
}
+static void imap_logger_noop(int direction, const char * str, size_t size)
+{
+ /* inhibit logging */
+}
+
static void imap_logger_cmd(int direction, const char * str, size_t size)
{
gchar *buf;
else {
gchar tmp[64];
strncpy2(tmp, lines[i], 63);
- log_print(LOG_PROTOCOL, "IMAP4%c %s[... - %zd bytes more]\n", direction?'>':'<', tmp,
+ log_print(LOG_PROTOCOL, "IMAP4%c %s[... - %d bytes more]\n", direction?'>':'<', tmp,
llen-64);
}
i++;
}
#define ETPAN_DEFAULT_NETWORK_TIMEOUT 60
-static gboolean etpan_skip_ssl_cert_check = FALSE;
+gboolean etpan_skip_ssl_cert_check = FALSE;
extern void mailsasl_ref(void);
void imap_main_init(gboolean skip_ssl_cert_check)
void imap_main_done(void)
{
+ imap_disconnect_all();
etpan_thread_manager_stop(thread_manager);
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+ return;
+#endif
etpan_thread_manager_join(thread_manager);
g_source_remove(thread_manager_signal);
return imap;
}
+static gboolean cb_show_error(gpointer data)
+{
+ mainwindow_show_error();
+ return FALSE;
+}
static void generic_cb(int cancelled, void * result, void * callback_data)
{
op->imap->imap_response_info->rsp_alert) {
log_error(LOG_PROTOCOL, "IMAP4< Alert: %s\n",
op->imap->imap_response_info->rsp_alert);
- mainwindow_show_error();
+ g_timeout_add(10, cb_show_error, NULL);
}
op->finished = 1;
}
g_warning("no cert presented.\n");
return 0;
}
- cert = d2i_X509(NULL, &certificate, len);
+ cert = d2i_X509(NULL, (const unsigned char **)&certificate, len);
if (cert == NULL) {
- g_warning("can't get cert\n");
+ g_warning("IMAP: can't get cert\n");
return 0;
} else if (ssl_certificate_check(cert, NULL,
(gchar *)param->server, (gushort)param->port) == TRUE) {
X509_free(cert);
return -1;
}
-#else
- return 0;
+#elif USE_GNUTLS
+ struct connect_param *param = (struct connect_param *)data;
+ gnutls_x509_crt cert = NULL;
+ gnutls_datum tmp;
+
+ if (certificate == NULL || len < 0) {
+ g_warning("no cert presented.\n");
+ return 0;
+ }
+
+ tmp.data = malloc(len);
+ memcpy(tmp.data, certificate, len);
+ tmp.size = len;
+ gnutls_x509_crt_init(&cert);
+ if (gnutls_x509_crt_import(cert, &tmp, GNUTLS_X509_FMT_DER) < 0) {
+ g_warning("IMAP: can't get cert\n");
+ return 0;
+ } else if (ssl_certificate_check(cert, (guint)-1, NULL,
+ (gchar *)param->server, (gushort)param->port) == TRUE) {
+ gnutls_x509_crt_deinit(cert);
+ return 0;
+ } else {
+ gnutls_x509_crt_deinit(cert);
+ return -1;
+ }
#endif
+ return 0;
}
static void connect_ssl_run(struct etpan_thread_op * op)
#endif
result->error = r;
+ if (param->imap->imap_response)
+ imap_logger_cmd(0, param->imap->imap_response, strlen(param->imap->imap_response));
debug_print("imap login run - end %i\n", r);
}
int imap_threaded_select(Folder * folder, const char * mb,
gint * exists, gint * recent, gint * unseen,
- guint32 * uid_validity)
+ guint32 * uid_validity,gint *can_create_flags,
+ GSList **ok_flags)
{
struct select_param param;
struct select_result result;
mailimap * imap;
-
+
debug_print("imap select - begin\n");
imap = get_imap(folder);
* recent = imap->imap_selection_info->sel_recent;
* unseen = imap->imap_selection_info->sel_unseen;
* uid_validity = imap->imap_selection_info->sel_uidvalidity;
-
+ * can_create_flags = FALSE;
+
+ if (imap->imap_selection_info->sel_perm_flags) {
+ GSList *t_flags = NULL;
+ clistiter *cur =
+ clist_begin(imap->imap_selection_info->sel_perm_flags);
+ for (; cur; cur = clist_next(cur)) {
+ struct mailimap_flag_perm *flag = (struct mailimap_flag_perm *)clist_content(cur);
+ if (flag->fl_type == MAILIMAP_FLAG_PERM_ALL)
+ *can_create_flags = TRUE;
+ else if (flag->fl_flag &&
+ flag->fl_flag->fl_type == 6 &&
+ !strcmp(flag->fl_flag->fl_data.fl_extension, "*"))
+ *can_create_flags = TRUE;
+ if (ok_flags) {
+ MsgPermFlags c_flag = 0;
+ switch (flag->fl_flag->fl_type) {
+ case MAILIMAP_FLAG_ANSWERED:
+ c_flag = IMAP_FLAG_ANSWERED;
+ break;
+ case MAILIMAP_FLAG_FLAGGED:
+ c_flag = IMAP_FLAG_FLAGGED;
+ break;
+ case MAILIMAP_FLAG_DELETED:
+ c_flag = IMAP_FLAG_DELETED;
+ break;
+ case MAILIMAP_FLAG_DRAFT:
+ c_flag = IMAP_FLAG_DRAFT;
+ break;
+ case MAILIMAP_FLAG_SEEN:
+ c_flag = IMAP_FLAG_SEEN;
+ break;
+ case MAILIMAP_FLAG_KEYWORD:
+ if (!strcasecmp(flag->fl_flag->fl_data.fl_keyword, "$Forwarded"))
+ c_flag = IMAP_FLAG_FORWARDED;
+ break;
+ default:
+ break;
+ }
+ if (c_flag != 0) {
+ t_flags = g_slist_prepend(t_flags,
+ GUINT_TO_POINTER(c_flag));
+ }
+ }
+ }
+ if (ok_flags)
+ *ok_flags = t_flags;
+ }
debug_print("imap select - end\n");
return result.error;
NULL, NULL, NULL, NULL, NULL,
NULL, 0, NULL, NULL, NULL);
break;
+ case IMAP_SEARCH_TYPE_FORWARDED:
+ search_type_key = mailimap_search_key_new(MAILIMAP_SEARCH_KEY_KEYWORD,
+ NULL, NULL, NULL, NULL, NULL,
+ strdup("$Forwarded"), NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, 0,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, 0, NULL, NULL, NULL);
+ break;
}
if (search_type_key != NULL) {
CHECK_IMAP();
fetch_result = NULL;
- mailstream_logger = NULL;
+ mailstream_logger = imap_logger_noop;
log_print(LOG_PROTOCOL, "IMAP4- [fetching UIDs...]\n");
r = imap_get_messages_list(param->imap, param->first_index,
-static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn);
+static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn, GSList **tags);
static int
result_to_uid_flags_list(clist * fetch_result, carray ** result)
int r;
int res;
carray * tab;
-
+ GSList *tags = NULL;
+
tab = carray_new(128);
if (tab == NULL) {
res = MAILIMAP_ERROR_MEMORY;
int flags;
int * pflags;
+ tags = NULL;
+
msg_att = clist_content(cur);
uid = 0;
if (att_dyn == NULL)
continue;
- flags = imap_flags_to_flags(att_dyn);
+ flags = imap_flags_to_flags(att_dyn, &tags);
puid = malloc(sizeof(* puid));
if (puid == NULL) {
res = MAILIMAP_ERROR_MEMORY;
goto free_list;
}
+ r = carray_add(tab, tags, NULL);
+ if (r < 0) {
+ free(pflags);
+ res = MAILIMAP_ERROR_MEMORY;
+ goto free_list;
+ }
}
* result = tab;
free_list:
imap_fetch_uid_flags_list_free(tab);
+ slist_free_strings(tags);
+ g_slist_free(tags);
err:
return res;
}
param.imap = imap;
param.first_index = first_index;
- mailstream_logger = NULL;
+ mailstream_logger = imap_logger_noop;
log_print(LOG_PROTOCOL, "IMAP4- [fetching flags...]\n");
threaded_run(folder, ¶m, &result, fetch_uid_flags_run);
{
unsigned int i;
- for(i = 0 ; i < carray_count(uid_flags_list) ; i ++) {
+ for(i = 0 ; i < carray_count(uid_flags_list) ; i += 3) {
void * data;
data = carray_get(uid_flags_list, i);
free(data);
+ data = carray_get(uid_flags_list, i + 1);
+ free(data);
}
carray_free(uid_flags_list);
}
}
r = fwrite(content, 1, content_size, f);
- if (r == 0) {
+ if (r < content_size) {
+ result->error = MAILIMAP_ERROR_FETCH;
goto fclose;
}
r = fclose(f);
if (r == EOF) {
- g_unlink(param->filename);
- goto close;
+ result->error = MAILIMAP_ERROR_FETCH;
+ goto unlink;
}
goto free;
close:
close(fd);
unlink:
- g_unlink(param->filename);
+ claws_unlink(param->filename);
free:
+ /* mmap_string_unref is a simple free in libetpan
+ * when it has MMAP_UNAVAILABLE defined */
if (mmap_string_unref(content) != 0)
free(content);
}
- debug_print("imap fetch_content run - end %i\n", r);
+ debug_print("imap fetch_content run - end %i\n", result->error);
}
int imap_threaded_fetch_content(Folder * folder, uint32_t msg_index,
-static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn)
+static int imap_flags_to_flags(struct mailimap_msg_att_dynamic * att_dyn, GSList **s_tags)
{
int flags;
clist * flag_list;
clistiter * cur;
-
+ GSList *tags = NULL;
+
flags = MSG_UNREAD;
flag_list = att_dyn->att_list;
flags &= ~MSG_UNREAD;
flags &= ~MSG_NEW;
break;
+ case MAILIMAP_FLAG_KEYWORD:
+ if (!strcasecmp(flag_fetch->fl_flag->fl_data.fl_keyword, "$Forwarded"))
+ flags |= MSG_FORWARDED;
+ else if (s_tags)
+ tags = g_slist_prepend(tags, g_strdup(flag_fetch->fl_flag->fl_data.fl_keyword));
+ break;
}
}
}
-
+ if (s_tags)
+ *s_tags = tags;
return flags;
}
}
static struct imap_fetch_env_info *
-fetch_to_env_info(struct mailimap_msg_att * msg_att)
+fetch_to_env_info(struct mailimap_msg_att * msg_att, GSList **tags)
{
struct imap_fetch_env_info * info;
uint32_t uid;
char * headers;
size_t size;
struct mailimap_msg_att_dynamic * att_dyn;
-
+
imap_get_msg_att_info(msg_att, &uid, &headers, &size,
&att_dyn);
info->uid = uid;
info->headers = strdup(headers);
info->size = size;
- info->flags = imap_flags_to_flags(att_dyn);
+ info->flags = imap_flags_to_flags(att_dyn, tags);
return info;
}
clistiter * cur;
unsigned int i;
carray * env_list;
+
i = 0;
-
env_list = carray_new(16);
for(cur = clist_begin(fetch_result) ; cur != NULL ;
cur = clist_next(cur)) {
struct mailimap_msg_att * msg_att;
struct imap_fetch_env_info * env_info;
-
+ GSList *tags = NULL;
+
msg_att = clist_content(cur);
- env_info = fetch_to_env_info(msg_att);
+ env_info = fetch_to_env_info(msg_att, &tags);
if (!env_info)
return MAILIMAP_ERROR_MEMORY;
carray_add(env_list, env_info, NULL);
+ carray_add(env_list, tags, NULL);
}
* p_env_list = env_list;
{
unsigned int i;
- for(i = 0 ; i < carray_count(env_list) ; i ++) {
+ for(i = 0 ; i < carray_count(env_list) ; i += 2) {
struct imap_fetch_env_info * env_info;
env_info = carray_get(env_list, i);
int r;
char * data;
size_t size;
+#ifndef G_OS_WIN32
struct stat stat_buf;
int fd;
+#endif
guint32 uid = 0, val = 0;
param = op->param;
CHECK_IMAP();
+#ifndef G_OS_WIN32
r = stat(param->filename, &stat_buf);
if (r < 0) {
result->error = MAILIMAP_ERROR_APPEND;
result->error = MAILIMAP_ERROR_APPEND;
return;
}
-
+#else
+ data = file_read_to_str_no_recode(param->filename);
+ if (data == NULL) {
+ result->error = MAILIMAP_ERROR_APPEND;
+ return;
+ }
+ size = strlen(data);
+#endif
mailstream_logger = imap_logger_append;
r = mailimap_uidplus_append(param->imap, param->mailbox,
mailstream_logger = imap_logger_cmd;
+#ifndef G_OS_WIN32
munmap(data, size);
close(fd);
+#else
+ g_free(data);
+#endif
result->error = r;
result->uid = uid;
#define ENV_BUFFER_SIZE 512
-
+#ifndef G_OS_WIN32
static void do_exec_command(int fd, const char * command,
const char * servername, uint16_t port)
{
exit(0);
}
-#ifdef SOLARIS
if (servername)
- snprintf(env_buffer, ENV_BUFFER_SIZE,
- "ETPANSERVER=%s", servername);
+ g_setenv("ETPANSERVER", servername, TRUE);
else
- snprintf(env_buffer, ENV_BUFFER_SIZE, "ETPANSERVER=");
- putenv(env_buffer);
-#else
- if (servername)
- setenv("ETPANSERVER", servername, 1);
- else
- unsetenv("ETPANSERVER");
-#endif
+ g_unsetenv("ETPANSERVER");
-#ifdef SOLARIS
- if (port)
- snprintf(env_buffer, ENV_BUFFER_SIZE, "ETPANPORT=%d", port);
- else
- snprintf(env_buffer, ENV_BUFFER_SIZE, "ETPANPORT=");
- putenv(env_buffer);
-#else
if (port) {
char porttext[20];
snprintf(porttext, sizeof(porttext), "%d", port);
- setenv("ETPANPORT", porttext, 1);
+ g_setenv("ETPANPORT", porttext, TRUE);
}
else {
- unsetenv("ETPANPORT");
+ g_unsetenv("ETPANPORT");
}
-#endif
/* Not a lot we can do if there's an error other than bail. */
if (dup2(fd, 0) == -1)
return result.error;
}
+#endif /* G_OS_WIN32 */
void imap_threaded_cancel(Folder * folder)
{