/* Generated by GOB (v2.0.15)   (do not edit directly) */

/* End world hunger, donate to the World Food Programme, http://www.wfp.org */

#define GOB_VERSION_MAJOR 2
#define GOB_VERSION_MINOR 0
#define GOB_VERSION_PATCHLEVEL 15

#define selfp (self->_priv)

#include "mn-imap-mailbox.h"

#include "mn-imap-mailbox-private.h"

#ifdef G_LIKELY
#define ___GOB_LIKELY(expr) G_LIKELY(expr)
#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)
#else /* ! G_LIKELY */
#define ___GOB_LIKELY(expr) (expr)
#define ___GOB_UNLIKELY(expr) (expr)
#endif /* G_LIKELY */

#line 42 "src/mn-imap-mailbox.gob"

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include "mn-mailbox-private.h"
#include "mn-authenticated-mailbox-private.h"
#include "mn-pi-mailbox-private.h"
#include "mn-util.h"
#include "mn-message-mime.h"

#define HAS_CURRENT_TAG(response, priv)	(! strcmp((response)->tag, (priv)->tag))
#define IS(response, token)		(! g_ascii_strcasecmp((response)->response, (token)))
#define IS_OK(response)			IS(response, "OK")
#define IS_NO(response)			IS(response, "NO")
#define IS_BAD(response)		IS(response, "BAD")
#define IS_BYE(response)		IS(response, "BYE")

enum
{
  STATE_GREETING = MN_CLIENT_SESSION_INITIAL_STATE,
  STATE_CAPABILITY,
#if WITH_SSL
  STATE_STARTTLS,
#endif
#if WITH_SASL
  STATE_AUTHENTICATE,
#endif
  STATE_LOGIN,
  STATE_EXAMINE,
  STATE_SEARCH_UNSEEN,
  STATE_SEARCH_RECENT,
  STATE_FETCH_UID,
  STATE_FETCH,
  STATE_IDLE,
  STATE_LOGOUT
};

typedef enum
{
  IDLE_STATE_PRE_IDLE,
  IDLE_STATE_IDLE,
  IDLE_STATE_POST_IDLE
} IdleState;

struct _MNClientSessionPrivate
{
  MN_PI_MAILBOX_SESSION_PRIVATE;
  MNIMAPMailbox			*self;

  const char			*server_software;
  gboolean			server_software_supports_idle;

  int				numeric_tag;
  char				tag[5];

  char				**capabilities;
  GSList			*auth_mechanisms;
  gboolean			authenticated;

  /*
   * RFC 3501 specifies that UIDVALIDITY is a 32-bit number, but we do
   * not need it to be one. Use a string for interoperability purposes
   * (in case some server vendors did not read the RFC properly).
   */
  char				*uidvalidity;

  int				num_errors;
  GHashTable			*messages;

#if WITH_SSL
  gboolean			starttls_completed;
#endif
#if WITH_SASL
  GSList			*sasl_remaining_mechanisms;
  const char			*sasl_mechanism;
#endif

  IdleState			idle_state;
  unsigned int			idle_inactivity_timeout_id;
  gboolean			idle_inactivity;
  gboolean			could_idle;	/* could idle at least once */
};

struct _MNClientSessionResponse
{
  char		*continuation;
  char		*tag;
  char		*response;
  char		*code;
  char		*arguments;
};

typedef struct
{
  MNMessage		*message;
  char			*mid;
  int			number;
  MNMessageFlags	flags;
} MessageInfo;

int mn_imap_mailbox_default_ports[MN_PI_MAILBOX_N_CONNECTION_TYPES] = { 143, 143, 993 };

/* variable taken from Evolution (camel-utf8.c) */
static const char *utf7_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";

#line 133 "mn-imap-mailbox.c"
static const GEnumValue _mn_imap_mailbox_use_idle_values[] = {
	{ MN_IMAP_MAILBOX_USE_IDLE_NEVER, (char *)"MN_IMAP_MAILBOX_USE_IDLE_NEVER", (char *)"never" },
	{ MN_IMAP_MAILBOX_USE_IDLE_AUTODETECT, (char *)"MN_IMAP_MAILBOX_USE_IDLE_AUTODETECT", (char *)"autodetect" },
	{ MN_IMAP_MAILBOX_USE_IDLE_ALWAYS, (char *)"MN_IMAP_MAILBOX_USE_IDLE_ALWAYS", (char *)"always" },
	{ 0, NULL, NULL }
};

GType
mn_imap_mailbox_use_idle_get_type (void)
{
	static GType type = 0;
	if ___GOB_UNLIKELY(type == 0)
		type = g_enum_register_static ("MNIMAPMailboxUseIDLE", _mn_imap_mailbox_use_idle_values);
	return type;
}

/* self casting macros */
#define SELF(x) MN_IMAP_MAILBOX(x)
#define SELF_CONST(x) MN_IMAP_MAILBOX_CONST(x)
#define IS_SELF(x) MN_IS_IMAP_MAILBOX(x)
#define TYPE_SELF MN_TYPE_IMAP_MAILBOX
#define SELF_CLASS(x) MN_IMAP_MAILBOX_CLASS(x)

#define SELF_GET_CLASS(x) MN_IMAP_MAILBOX_GET_CLASS(x)

/* self typedefs */
typedef MNIMAPMailbox Self;
typedef MNIMAPMailboxClass SelfClass;

/* here are local prototypes */
static void ___object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void ___object_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
#line 179 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_class_init (MNIMAPMailboxClass * class);
#line 168 "mn-imap-mailbox.c"
#line 185 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_init (MNIMAPMailbox * self);
#line 171 "mn-imap-mailbox.c"
#line 190 "src/mn-imap-mailbox.gob"
static void ___3_mn_imap_mailbox_seal (MNMailbox * mailbox);
#line 174 "mn-imap-mailbox.c"
#line 219 "src/mn-imap-mailbox.gob"
static MNMailbox * ___4_mn_imap_mailbox_parse_uri (MNMailbox * dummy, const char * uri);
#line 177 "mn-imap-mailbox.c"
#line 289 "src/mn-imap-mailbox.gob"
static gboolean mn_imap_mailbox_split_uri_location (const char * location, int maxlen, char * hostport, char * path, gboolean * has_path);
#line 180 "mn-imap-mailbox.c"
#line 316 "src/mn-imap-mailbox.gob"
static void ___6_mn_imap_mailbox_removed (MNMailbox * mailbox);
#line 183 "mn-imap-mailbox.c"
#line 332 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_greeting_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 186 "mn-imap-mailbox.c"
#line 362 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_capability_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 189 "mn-imap-mailbox.c"
#line 369 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_capability_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 192 "mn-imap-mailbox.c"
#line 404 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_starttls_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 195 "mn-imap-mailbox.c"
#line 416 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_starttls_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 198 "mn-imap-mailbox.c"
#line 452 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_authenticate_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 201 "mn-imap-mailbox.c"
#line 485 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_authenticate_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 204 "mn-imap-mailbox.c"
#line 545 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_login_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 207 "mn-imap-mailbox.c"
#line 574 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_login_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 210 "mn-imap-mailbox.c"
#line 602 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_examine_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 213 "mn-imap-mailbox.c"
#line 620 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_examine_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 216 "mn-imap-mailbox.c"
#line 662 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_search_unseen_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 219 "mn-imap-mailbox.c"
#line 676 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_search_unseen_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 222 "mn-imap-mailbox.c"
#line 733 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_search_recent_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 225 "mn-imap-mailbox.c"
#line 740 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_search_recent_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 228 "mn-imap-mailbox.c"
#line 800 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_fetch_uid_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 231 "mn-imap-mailbox.c"
#line 820 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_build_fetch_uid_set_cb (gpointer key, gpointer value, gpointer user_data);
#line 234 "mn-imap-mailbox.c"
#line 832 "src/mn-imap-mailbox.gob"
static char * mn_imap_mailbox_parse_fetch_uid_response (const char * response);
#line 237 "mn-imap-mailbox.c"
#line 855 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_fetch_uid_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 240 "mn-imap-mailbox.c"
#line 925 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_fetch_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 243 "mn-imap-mailbox.c"
#line 949 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_build_fetch_set_cb (gpointer key, gpointer value, gpointer user_data);
#line 246 "mn-imap-mailbox.c"
#line 964 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_fetch_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 249 "mn-imap-mailbox.c"
#line 1060 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_idle_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 252 "mn-imap-mailbox.c"
#line 1103 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_idle_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 255 "mn-imap-mailbox.c"
#line 1201 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_enter_logout_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 258 "mn-imap-mailbox.c"
#line 1208 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_handle_logout_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 261 "mn-imap-mailbox.c"
#line 1228 "src/mn-imap-mailbox.gob"
static void ___21_mn_imap_mailbox_authenticated_check (MNAuthenticatedMailbox * mailbox);
#line 264 "mn-imap-mailbox.c"
#line 1337 "src/mn-imap-mailbox.gob"
static MNClientSessionResponse * mn_imap_mailbox_response_new_cb (MNClientSession * session, const char * input, MNClientSessionPrivate * priv);
#line 267 "mn-imap-mailbox.c"
#line 1413 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_response_free_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 270 "mn-imap-mailbox.c"
#line 1426 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_default_handler (MNClientSessionResponse * response, MNClientSessionPrivate * priv, int error_code_when_bye);
#line 273 "mn-imap-mailbox.c"
#line 1437 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_pre_read_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 276 "mn-imap-mailbox.c"
#line 1458 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_post_read_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 279 "mn-imap-mailbox.c"
#line 1475 "src/mn-imap-mailbox.gob"
static gboolean mn_imap_mailbox_idle_inactivity_timeout_cb (gpointer data);
#line 282 "mn-imap-mailbox.c"
#line 1496 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_session_write (MNClientSessionPrivate * priv, const char * format, ...) G_GNUC_PRINTF(2, 3);
#line 285 "mn-imap-mailbox.c"
#line 1516 "src/mn-imap-mailbox.gob"
static gboolean mn_imap_mailbox_session_handle_capability_code (MNClientSessionPrivate * priv, MNClientSessionResponse * response);
#line 288 "mn-imap-mailbox.c"
#line 1537 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_session_parse_capabilities (MNClientSessionPrivate * priv, const char * capabilities);
#line 291 "mn-imap-mailbox.c"
#line 1564 "src/mn-imap-mailbox.gob"
static gboolean mn_imap_mailbox_session_has_capability (MNClientSessionPrivate * priv, const char * capability);
#line 294 "mn-imap-mailbox.c"
#line 1579 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_session_after_capability (MNClientSessionPrivate * priv);
#line 297 "mn-imap-mailbox.c"
#line 1603 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_session_authenticate (MNClientSessionPrivate * priv);
#line 300 "mn-imap-mailbox.c"
#line 1643 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_session_authenticate_fallback (MNClientSessionPrivate * priv, gboolean tried_login);
#line 303 "mn-imap-mailbox.c"
#line 1689 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_session_detect_imapd (MNClientSession * session, MNClientSessionResponse * greeting_response, MNClientSessionPrivate * priv);
#line 306 "mn-imap-mailbox.c"
#line 1713 "src/mn-imap-mailbox.gob"
static int mn_imap_mailbox_session_got_messages (MNClientSessionPrivate * priv);
#line 309 "mn-imap-mailbox.c"
#line 1751 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_get_messages_list_cb (gpointer key, gpointer value, gpointer user_data);
#line 312 "mn-imap-mailbox.c"
#line 1761 "src/mn-imap-mailbox.gob"
static MessageInfo * mn_imap_mailbox_session_get_message_info (MNClientSessionPrivate * priv, int number);
#line 315 "mn-imap-mailbox.c"
#line 1768 "src/mn-imap-mailbox.gob"
static MessageInfo * mn_imap_mailbox_session_ensure_message_info (MNClientSessionPrivate * priv, int number);
#line 318 "mn-imap-mailbox.c"
#line 1784 "src/mn-imap-mailbox.gob"
static MessageInfo * mn_imap_mailbox_message_info_new (int number);
#line 321 "mn-imap-mailbox.c"
#line 1795 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_message_info_free (MessageInfo * info);
#line 324 "mn-imap-mailbox.c"
#line 1812 "src/mn-imap-mailbox.gob"
static char * mn_imap_mailbox_quote (const char * str);
#line 327 "mn-imap-mailbox.c"
#line 1837 "src/mn-imap-mailbox.gob"
static char * mn_imap_mailbox_utf8_to_imap_utf7 (const char * str);
#line 330 "mn-imap-mailbox.c"
#line 1896 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_imap_utf7_closeb64 (GString * out, guint32 v, guint32 i);
#line 333 "mn-imap-mailbox.c"
#line 1932 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_lock (MNIMAPMailbox * self);
#line 336 "mn-imap-mailbox.c"
#line 1938 "src/mn-imap-mailbox.gob"
static void mn_imap_mailbox_unlock (MNIMAPMailbox * self);
#line 339 "mn-imap-mailbox.c"

enum {
	PROP_0,
	PROP_MAILBOX,
	PROP_USE_IDLE_EXTENSION
};

/* pointer to the class of our parent */
static MNPIMailboxClass *parent_class = NULL;

/* Short form macros */
#define self_split_uri_location mn_imap_mailbox_split_uri_location
#define self_handle_greeting_cb mn_imap_mailbox_handle_greeting_cb
#define self_enter_capability_cb mn_imap_mailbox_enter_capability_cb
#define self_handle_capability_cb mn_imap_mailbox_handle_capability_cb
#define self_enter_starttls_cb mn_imap_mailbox_enter_starttls_cb
#define self_handle_starttls_cb mn_imap_mailbox_handle_starttls_cb
#define self_enter_authenticate_cb mn_imap_mailbox_enter_authenticate_cb
#define self_handle_authenticate_cb mn_imap_mailbox_handle_authenticate_cb
#define self_enter_login_cb mn_imap_mailbox_enter_login_cb
#define self_handle_login_cb mn_imap_mailbox_handle_login_cb
#define self_enter_examine_cb mn_imap_mailbox_enter_examine_cb
#define self_handle_examine_cb mn_imap_mailbox_handle_examine_cb
#define self_enter_search_unseen_cb mn_imap_mailbox_enter_search_unseen_cb
#define self_handle_search_unseen_cb mn_imap_mailbox_handle_search_unseen_cb
#define self_enter_search_recent_cb mn_imap_mailbox_enter_search_recent_cb
#define self_handle_search_recent_cb mn_imap_mailbox_handle_search_recent_cb
#define self_enter_fetch_uid_cb mn_imap_mailbox_enter_fetch_uid_cb
#define self_build_fetch_uid_set_cb mn_imap_mailbox_build_fetch_uid_set_cb
#define self_parse_fetch_uid_response mn_imap_mailbox_parse_fetch_uid_response
#define self_handle_fetch_uid_cb mn_imap_mailbox_handle_fetch_uid_cb
#define self_enter_fetch_cb mn_imap_mailbox_enter_fetch_cb
#define self_build_fetch_set_cb mn_imap_mailbox_build_fetch_set_cb
#define self_handle_fetch_cb mn_imap_mailbox_handle_fetch_cb
#define self_enter_idle_cb mn_imap_mailbox_enter_idle_cb
#define self_handle_idle_cb mn_imap_mailbox_handle_idle_cb
#define self_enter_logout_cb mn_imap_mailbox_enter_logout_cb
#define self_handle_logout_cb mn_imap_mailbox_handle_logout_cb
#define self_response_new_cb mn_imap_mailbox_response_new_cb
#define self_response_free_cb mn_imap_mailbox_response_free_cb
#define self_default_handler mn_imap_mailbox_default_handler
#define self_pre_read_cb mn_imap_mailbox_pre_read_cb
#define self_post_read_cb mn_imap_mailbox_post_read_cb
#define self_idle_inactivity_timeout_cb mn_imap_mailbox_idle_inactivity_timeout_cb
#define self_session_write mn_imap_mailbox_session_write
#define self_session_handle_capability_code mn_imap_mailbox_session_handle_capability_code
#define self_session_parse_capabilities mn_imap_mailbox_session_parse_capabilities
#define self_session_has_capability mn_imap_mailbox_session_has_capability
#define self_session_after_capability mn_imap_mailbox_session_after_capability
#define self_session_authenticate mn_imap_mailbox_session_authenticate
#define self_session_authenticate_fallback mn_imap_mailbox_session_authenticate_fallback
#define self_session_detect_imapd mn_imap_mailbox_session_detect_imapd
#define self_session_got_messages mn_imap_mailbox_session_got_messages
#define self_get_messages_list_cb mn_imap_mailbox_get_messages_list_cb
#define self_session_get_message_info mn_imap_mailbox_session_get_message_info
#define self_session_ensure_message_info mn_imap_mailbox_session_ensure_message_info
#define self_message_info_new mn_imap_mailbox_message_info_new
#define self_message_info_free mn_imap_mailbox_message_info_free
#define self_quote mn_imap_mailbox_quote
#define self_utf8_to_imap_utf7 mn_imap_mailbox_utf8_to_imap_utf7
#define self_imap_utf7_closeb64 mn_imap_mailbox_imap_utf7_closeb64
#define self_build_name mn_imap_mailbox_build_name
#define self_lock mn_imap_mailbox_lock
#define self_unlock mn_imap_mailbox_unlock
GType
mn_imap_mailbox_get_type (void)
{
	static GType type = 0;

	if ___GOB_UNLIKELY(type == 0) {
		static const GTypeInfo info = {
			sizeof (MNIMAPMailboxClass),
			(GBaseInitFunc) NULL,
			(GBaseFinalizeFunc) NULL,
			(GClassInitFunc) mn_imap_mailbox_class_init,
			(GClassFinalizeFunc) NULL,
			NULL /* class_data */,
			sizeof (MNIMAPMailbox),
			0 /* n_preallocs */,
			(GInstanceInitFunc) mn_imap_mailbox_init,
			NULL
		};

		type = g_type_register_static (MN_TYPE_PI_MAILBOX, "MNIMAPMailbox", &info, (GTypeFlags)0);
	}

	return type;
}

/* a macro for creating a new object of our type */
#define GET_NEW ((MNIMAPMailbox *)g_object_new(mn_imap_mailbox_get_type(), NULL))

/* a function for creating a new object of our type */
#include <stdarg.h>
static MNIMAPMailbox * GET_NEW_VARG (const char *first, ...) G_GNUC_UNUSED;
static MNIMAPMailbox *
GET_NEW_VARG (const char *first, ...)
{
	MNIMAPMailbox *ret;
	va_list ap;
	va_start (ap, first);
	ret = (MNIMAPMailbox *)g_object_new_valist (mn_imap_mailbox_get_type (), first, ap);
	va_end (ap);
	return ret;
}


static void
___finalize(GObject *obj_self)
{
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::finalize"
	MNIMAPMailbox *self G_GNUC_UNUSED = MN_IMAP_MAILBOX (obj_self);
	gpointer priv G_GNUC_UNUSED = self->_priv;
	if(G_OBJECT_CLASS(parent_class)->finalize) \
		(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);
#line 160 "src/mn-imap-mailbox.gob"
	if(self->_priv->mutex) { g_mutex_free ((gpointer) self->_priv->mutex); self->_priv->mutex = NULL; }
#line 457 "mn-imap-mailbox.c"
#line 164 "src/mn-imap-mailbox.gob"
	if(self->mailbox) { g_free ((gpointer) self->mailbox); self->mailbox = NULL; }
#line 460 "mn-imap-mailbox.c"
}
#undef __GOB_FUNCTION__

#line 179 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_class_init (MNIMAPMailboxClass * class G_GNUC_UNUSED)
{
#line 468 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::class_init"
	GObjectClass *g_object_class G_GNUC_UNUSED = (GObjectClass*) class;
	MNMailboxClass *mn_mailbox_class = (MNMailboxClass *)class;
	MNAuthenticatedMailboxClass *mn_authenticated_mailbox_class = (MNAuthenticatedMailboxClass *)class;

	g_type_class_add_private(class,sizeof(MNIMAPMailboxPrivate));

	parent_class = g_type_class_ref (MN_TYPE_PI_MAILBOX);

#line 190 "src/mn-imap-mailbox.gob"
	mn_mailbox_class->seal = ___3_mn_imap_mailbox_seal;
#line 219 "src/mn-imap-mailbox.gob"
	mn_mailbox_class->parse_uri = ___4_mn_imap_mailbox_parse_uri;
#line 316 "src/mn-imap-mailbox.gob"
	mn_mailbox_class->removed = ___6_mn_imap_mailbox_removed;
#line 1228 "src/mn-imap-mailbox.gob"
	mn_authenticated_mailbox_class->authenticated_check = ___21_mn_imap_mailbox_authenticated_check;
#line 486 "mn-imap-mailbox.c"
	g_object_class->finalize = ___finalize;
	g_object_class->get_property = ___object_get_property;
	g_object_class->set_property = ___object_set_property;
    {
	GParamSpec   *param_spec;

	param_spec = g_param_spec_string
		("mailbox" /* name */,
		 NULL /* nick */,
		 NULL /* blurb */,
		 "INBOX" /* default_value */,
		 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | MN_MAILBOX_PARAM_IGNORE_CASE | MN_MAILBOX_PARAM_REQUIRED | MN_MAILBOX_PARAM_LOAD_SAVE | G_PARAM_CONSTRUCT));
	g_object_class_install_property (g_object_class,
		PROP_MAILBOX,
		param_spec);
	param_spec = g_param_spec_enum
		("use_idle_extension" /* name */,
		 NULL /* nick */,
		 NULL /* blurb */,
		 MN_TYPE_IMAP_MAILBOX_USE_IDLE /* enum_type */,
		 MN_IMAP_MAILBOX_USE_IDLE_AUTODETECT /* default_value */,
		 (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | MN_MAILBOX_PARAM_LOAD_SAVE | G_PARAM_CONSTRUCT));
	g_object_class_install_property (g_object_class,
		PROP_USE_IDLE_EXTENSION,
		param_spec);
    }
 {
#line 180 "src/mn-imap-mailbox.gob"

    MN_MAILBOX_CLASS(class)->type = "imap";
    MN_PI_MAILBOX_CLASS(class)->default_ports = mn_imap_mailbox_default_ports;
  
#line 519 "mn-imap-mailbox.c"
 }
}
#undef __GOB_FUNCTION__
#line 185 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_init (MNIMAPMailbox * self G_GNUC_UNUSED)
{
#line 527 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::init"
	self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self,MN_TYPE_IMAP_MAILBOX,MNIMAPMailboxPrivate);
#line 160 "src/mn-imap-mailbox.gob"
	self->_priv->mutex = g_mutex_new();
#line 532 "mn-imap-mailbox.c"
 {
#line 186 "src/mn-imap-mailbox.gob"

    mn_mailbox_set_format(MN_MAILBOX(self), "IMAP");
  
#line 538 "mn-imap-mailbox.c"
 }
}
#undef __GOB_FUNCTION__

static void
___object_set_property (GObject *object,
	guint property_id,
	const GValue *VAL G_GNUC_UNUSED,
	GParamSpec *pspec G_GNUC_UNUSED)
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::set_property"
{
	MNIMAPMailbox *self G_GNUC_UNUSED;

	self = MN_IMAP_MAILBOX (object);

	switch (property_id) {
	case PROP_MAILBOX:
		{
#line 165 "src/mn-imap-mailbox.gob"
{ char *old = self->mailbox; self->mailbox = g_value_dup_string (VAL); g_free (old); }
#line 559 "mn-imap-mailbox.c"
		}
		break;
	case PROP_USE_IDLE_EXTENSION:
		{
#line 173 "src/mn-imap-mailbox.gob"
self->use_idle_extension = g_value_get_enum (VAL);
#line 566 "mn-imap-mailbox.c"
		}
		break;
	default:
/* Apparently in g++ this is needed, glib is b0rk */
#ifndef __PRETTY_FUNCTION__
#  undef G_STRLOC
#  define G_STRLOC	__FILE__ ":" G_STRINGIFY (__LINE__)
#endif
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}
#undef __GOB_FUNCTION__

static void
___object_get_property (GObject *object,
	guint property_id,
	GValue *VAL G_GNUC_UNUSED,
	GParamSpec *pspec G_GNUC_UNUSED)
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::get_property"
{
	MNIMAPMailbox *self G_GNUC_UNUSED;

	self = MN_IMAP_MAILBOX (object);

	switch (property_id) {
	case PROP_MAILBOX:
		{
#line 165 "src/mn-imap-mailbox.gob"
g_value_set_string (VAL, self->mailbox);
#line 597 "mn-imap-mailbox.c"
		}
		break;
	case PROP_USE_IDLE_EXTENSION:
		{
#line 173 "src/mn-imap-mailbox.gob"
g_value_set_enum (VAL, self->use_idle_extension);
#line 604 "mn-imap-mailbox.c"
		}
		break;
	default:
/* Apparently in g++ this is needed, glib is b0rk */
#ifndef __PRETTY_FUNCTION__
#  undef G_STRLOC
#  define G_STRLOC	__FILE__ ":" G_STRINGIFY (__LINE__)
#endif
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}
#undef __GOB_FUNCTION__



#line 190 "src/mn-imap-mailbox.gob"
static void 
___3_mn_imap_mailbox_seal (MNMailbox * mailbox G_GNUC_UNUSED)
#line 624 "mn-imap-mailbox.c"
#define PARENT_HANDLER(___mailbox) \
	{ if(MN_MAILBOX_CLASS(parent_class)->seal) \
		(* MN_MAILBOX_CLASS(parent_class)->seal)(___mailbox); }
{
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::seal"
{
#line 192 "src/mn-imap-mailbox.gob"
	
    MNAuthenticatedMailbox *auth_mailbox = MN_AUTHENTICATED_MAILBOX(mailbox);
    Self *self = SELF(mailbox);

    PARENT_HANDLER(mailbox);

    if (! mailbox->runtime_name)
      mailbox->runtime_name = self_build_name(MN_AUTHENTICATED_MAILBOX(mailbox)->username,
					      MN_PI_MAILBOX(mailbox)->hostname,
					      self->mailbox);

#if WITH_SSL
    if (MN_PI_MAILBOX(self)->connection_type == MN_PI_MAILBOX_CONNECTION_TYPE_SSL)
      auth_mailbox->keyring_protocol = g_strdup("imaps");
    else
#endif
      auth_mailbox->keyring_protocol = g_strdup("imap");
  }}
#line 650 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 219 "src/mn-imap-mailbox.gob"
static MNMailbox * 
___4_mn_imap_mailbox_parse_uri (MNMailbox * dummy G_GNUC_UNUSED, const char * uri)
#line 657 "mn-imap-mailbox.c"
#define PARENT_HANDLER(___dummy,___uri) \
	((MN_MAILBOX_CLASS(parent_class)->parse_uri)? \
		(* MN_MAILBOX_CLASS(parent_class)->parse_uri)(___dummy,___uri): \
		((MNMailbox * )0))
{
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::parse_uri"
{
#line 221 "src/mn-imap-mailbox.gob"
	
    int len;
    int buflen;
    char *username = NULL;
    char *authmech = NULL;
    char *hostname;
    char *path = NULL;
    int port;
    MNMailbox *mailbox;

    len = strlen(uri);
    buflen = len + 1;

    {
      char scheme_buf[buflen];
      char auth_buf[buflen];
      char location_buf[buflen];
      char hostport_buf[buflen];
      char path_buf[buflen];
      char username_buf[buflen];
      char authmech_buf[buflen];
      char hostname_buf[buflen];
      gboolean has_path;
      gboolean has_authmech = FALSE;

      if (! mn_pi_mailbox_split_uri(uri, len, scheme_buf, auth_buf, location_buf))
	return NULL;

      if (strcmp(scheme_buf, "imap"))
	return NULL;

      if (! self_split_uri_location(location_buf, len, hostport_buf, path_buf, &has_path))
	return NULL;

      if (! mn_pi_mailbox_split_uri_auth(auth_buf, len, username_buf, authmech_buf, &has_authmech))
	return NULL;

      if (has_authmech && ! strcmp(authmech_buf, "*"))
	has_authmech = FALSE;

      mn_pi_mailbox_split_uri_hostport(hostport_buf, len, hostname_buf, &port);

      username = gnome_vfs_unescape_string(username_buf, NULL);
      if (has_authmech)
	authmech = gnome_vfs_unescape_string(authmech_buf, NULL);
      hostname = gnome_vfs_unescape_string(hostname_buf, NULL);
      if (has_path)
	path = gnome_vfs_unescape_string(path_buf, NULL);
    }

    mailbox = mn_mailbox_new("imap",
			     "username", username,
			     "authmech", authmech,
			     "hostname", hostname,
			     "port", port,
			     NULL);

    if (path)
      g_object_set(mailbox, MN_IMAP_MAILBOX_PROP_MAILBOX(path), NULL);

    g_free(username);
    g_free(authmech);
    g_free(hostname);
    g_free(path);

    return mailbox;
  }}
#line 733 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 289 "src/mn-imap-mailbox.gob"
static gboolean 
mn_imap_mailbox_split_uri_location (const char * location, int maxlen, char * hostport, char * path, gboolean * has_path)
{
#line 741 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::split_uri_location"
#line 289 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (location != NULL, (gboolean )0);
#line 289 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (hostport != NULL, (gboolean )0);
#line 289 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (path != NULL, (gboolean )0);
#line 289 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (has_path != NULL, (gboolean )0);
#line 751 "mn-imap-mailbox.c"
{
#line 295 "src/mn-imap-mailbox.gob"
	
    char *pat;
    int n;

    pat = g_strdup_printf("%%%i[^/]/%%%is", maxlen, maxlen);
    n = sscanf(location, pat, hostport, path);
    g_free(pat);

    g_return_val_if_fail(n >= 1, FALSE);

    *has_path = n == 2;
    if (*has_path)
      {
	/* we only handle enc_mailbox (see the RFC 2192 ABNF) */
	if (strspn(path, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$-_.+!*'(),%&=~:@/") != strlen(path))
	  return FALSE;		/* more than enc_mailbox, unhandled */
      }

    return TRUE;
  }}
#line 774 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 316 "src/mn-imap-mailbox.gob"
static void 
___6_mn_imap_mailbox_removed (MNMailbox * mailbox G_GNUC_UNUSED)
#line 780 "mn-imap-mailbox.c"
#define PARENT_HANDLER(___mailbox) \
	{ if(MN_MAILBOX_CLASS(parent_class)->removed) \
		(* MN_MAILBOX_CLASS(parent_class)->removed)(___mailbox); }
{
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::removed"
{
#line 318 "src/mn-imap-mailbox.gob"
	
    Self *self = SELF(mailbox);

    PARENT_HANDLER(mailbox);

    self_lock(self);
    if (selfp->idle_session)
      {
	mn_client_session_write(selfp->idle_session->session, "DONE");
	selfp->idle_session->idle_state = IDLE_STATE_POST_IDLE;
      }
    self_unlock(self);
  }}
#line 801 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 332 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_greeting_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 809 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_greeting_cb"
{
#line 336 "src/mn-imap-mailbox.gob"
	
    priv->session = session;

    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (! response->tag && IS_OK(response))
      {
	self_session_detect_imapd(session, response, priv);
	return self_session_handle_capability_code(priv, response)
	  ? self_session_after_capability(priv)
	  : STATE_CAPABILITY;
      }
    else if (! response->tag && IS(response, "PREAUTH"))
      {
	priv->authenticated = TRUE;
	self_session_detect_imapd(session, response, priv);
	return self_session_handle_capability_code(priv, response)
	  ? self_session_after_capability(priv)
	  : STATE_CAPABILITY;
      }
    else if (! response->tag && IS_BYE(response))
      return mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
    else
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
  }}
#line 838 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 362 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_capability_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 845 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_capability_cb"
{
#line 365 "src/mn-imap-mailbox.gob"
	
    return self_session_write(priv, "CAPABILITY");
  }}
#line 852 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 369 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_capability_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 859 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_capability_cb"
{
#line 373 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		return priv->capabilities
		  ? self_session_after_capability(priv)
		  : mn_client_session_set_error(session, MN_CLIENT_SESSION_ERROR_OTHER, _("server did not send capabilities"));
	      }
	    else if (IS_BAD(response))
	      {
		mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		return STATE_LOGOUT;
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (IS(response, "CAPABILITY"))
      {
	self_session_parse_capabilities(priv, response->arguments);
	return MN_CLIENT_SESSION_RESULT_CONTINUE;
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 893 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 404 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_starttls_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 900 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_starttls_cb"
{
#line 407 "src/mn-imap-mailbox.gob"
	
#if WITH_SSL
    return self_session_write(priv, "STARTTLS");
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SSL */
  }}
#line 912 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 416 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_starttls_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 919 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_starttls_cb"
{
#line 420 "src/mn-imap-mailbox.gob"
	
#if WITH_SSL
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		priv->starttls_completed = TRUE;
		return mn_client_session_enable_ssl(session)
		  ? STATE_CAPABILITY
		  : MN_CLIENT_SESSION_RESULT_DISCONNECT;
	      }
	    else if (IS_BAD(response))
	      {
		mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		return STATE_LOGOUT;
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SSL */
  }}
#line 954 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 452 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_authenticate_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 961 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_authenticate_cb"
{
#line 455 "src/mn-imap-mailbox.gob"
	
#if WITH_SASL
    priv->sasl_mechanism = NULL;

    if (mn_client_session_sasl_authentication_start(priv->session,
						    "imap",
						    priv->sasl_remaining_mechanisms,
						    priv->pi_mailbox->authmech,
						    &priv->sasl_mechanism,
						    NULL,	/* [1] */
						    NULL))	/* [1] */
      {
	g_assert(priv->sasl_mechanism != NULL);
	return self_session_write(priv, "AUTHENTICATE %s", priv->sasl_mechanism);
      }
    else
      return priv->auth_mailbox->auth_cancelled
	? STATE_LOGOUT
	: self_session_authenticate_fallback(priv, FALSE);

    /*
     * [1] RFC 3501 6.2.2 specifies that the IMAP protocol does not
     * support the initial client response feature of SASL.
     */
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SASL */
  }}
#line 994 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 485 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_authenticate_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1001 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_authenticate_cb"
{
#line 489 "src/mn-imap-mailbox.gob"
	
#if WITH_SASL
    if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		if (mn_client_session_sasl_authentication_done(session))
		  {
		    priv->authenticated = TRUE;

		    /*
		     * RFC 3501 2.2.2:
		     *
		     * A server MAY include a CAPABILITY response code
		     * in the tagged OK response of a successful
		     * AUTHENTICATE command in order to send
		     * capabilities automatically.  It is unnecessary
		     * for a client to send a separate CAPABILITY
		     * command if it recognizes these automatic
		     * capabilities.  This should only be done if a
		     * security layer was not negotiated by the
		     * AUTHENTICATE command, because the tagged OK
		     * response as part of an AUTHENTICATE command is
		     * not protected by encryption/integrity checking.
		     * [SASL] requires the client to re-issue a
		     * CAPABILITY command in this case.
		     */
		    return self_session_handle_capability_code(priv, response) && mn_client_session_sasl_get_ssf(session)
		      ? STATE_EXAMINE
		      : STATE_CAPABILITY;
		  }
		else
		  return MN_CLIENT_SESSION_RESULT_DISCONNECT;
	      }
	    else if (IS_NO(response) || IS_BAD(response))
	      {
		return priv->auth_mailbox->auth_cancelled
		  ? STATE_LOGOUT
		  : self_session_authenticate_fallback(priv, FALSE);
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (response->continuation)
      return mn_client_session_sasl_authentication_step(session, response->continuation);

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SASL */
  }}
#line 1060 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 545 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_login_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1067 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_login_cb"
{
#line 548 "src/mn-imap-mailbox.gob"
	
    if (self_session_has_capability(priv, "LOGINDISABLED"))
      {
	mn_client_session_notice(session, _("server advertised LOGINDISABLED, not using LOGIN authentication"));
	mn_client_session_set_error(session, MN_CLIENT_SESSION_ERROR_OTHER, _("unable to login"));
	return STATE_LOGOUT;
      }
    else
      {
	char *quoted_username;
	char *quoted_password;
	int result;

	if (! mn_authenticated_mailbox_fill_password(priv->auth_mailbox, TRUE))
	  return STATE_LOGOUT;

	quoted_username = self_quote(priv->auth_mailbox->username);
	quoted_password = self_quote(priv->auth_mailbox->runtime_password);
	result = self_session_write(priv, "LOGIN %s %s", quoted_username, quoted_password);
	g_free(quoted_username);
	g_free(quoted_password);

	return result;
      }
  }}
#line 1096 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 574 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_login_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1103 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_login_cb"
{
#line 578 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		priv->authenticated = TRUE;
		return self_session_handle_capability_code(priv, response)
		  ? STATE_EXAMINE
		  : STATE_CAPABILITY;
	      }
	    else if (IS_NO(response) || IS_BAD(response))
	      return self_session_authenticate_fallback(priv, TRUE);
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1130 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 602 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_examine_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1137 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_examine_cb"
{
#line 605 "src/mn-imap-mailbox.gob"
	
    char *utf7_mailbox;
    char *quoted_mailbox;
    int result;

    utf7_mailbox = self_utf8_to_imap_utf7(priv->self->mailbox);
    quoted_mailbox = self_quote(utf7_mailbox);
    g_free(utf7_mailbox);

    result = self_session_write(priv, "EXAMINE %s", quoted_mailbox);
    g_free(quoted_mailbox);

    return result;
  }}
#line 1155 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 620 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_examine_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1162 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_examine_cb"
{
#line 624 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      return STATE_SEARCH_UNSEEN;
	    else if (IS_NO(response) || IS_BAD(response))
	      {
		mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		return STATE_LOGOUT;
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (IS(response, "OK"))
      {
	if (response->code)
	  {
	    char **fields;

	    fields = g_strsplit(response->code, " ", 0);
	    if (g_strv_length(fields) == 2
		&& ! g_ascii_strcasecmp(fields[0], "UIDVALIDITY"))
	      {
		g_free(priv->uidvalidity);
		priv->uidvalidity = g_strdup(fields[1]);
	      }
	    g_strfreev(fields);
	  }
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1203 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 662 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_search_unseen_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1210 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_search_unseen_cb"
{
#line 665 "src/mn-imap-mailbox.gob"
	
    priv->num_errors = 0;

    if (priv->messages)
      g_hash_table_remove_all(priv->messages);
    else
      priv->messages = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) self_message_info_free);

    return self_session_write(priv, "SEARCH UNSEEN");
  }}
#line 1224 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 676 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_search_unseen_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1231 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_search_unseen_cb"
{
#line 680 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		/*
		 * Some uncompliant IMAP server implementations do not
		 * send an untagged SEARCH response when there are no
		 * search results (#18876). We are tolerant.
		 */
		if (g_hash_table_size(priv->messages) != 0)
		  return STATE_SEARCH_RECENT;
		else
		  return self_session_got_messages(priv);
	      }
	    else if (IS_NO(response) || IS_BAD(response))
	      {
		mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		return STATE_LOGOUT;
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (IS(response, "SEARCH"))
      {
	if (response->arguments)
	  {
	    char **strings;
	    int i;

	    strings = g_strsplit(response->arguments, " ", 0);

	    for (i = 0; strings[i]; i++)
	      if (mn_str_isnumeric(strings[i]))
		{
		  int n = atoi(strings[i]);
		  self_session_ensure_message_info(priv, n);
		}

	    g_strfreev(strings);
	  }

	return MN_CLIENT_SESSION_RESULT_CONTINUE;
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1287 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 733 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_search_recent_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1294 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_search_recent_cb"
{
#line 736 "src/mn-imap-mailbox.gob"
	
    return self_session_write(priv, "SEARCH RECENT");
  }}
#line 1301 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 740 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_search_recent_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1308 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_search_recent_cb"
{
#line 744 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		if (priv->uidvalidity)
		  return STATE_FETCH_UID;
		else
		  return STATE_FETCH;
	      }
	    else if (IS_NO(response) || IS_BAD(response))
	      {
		mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		return STATE_LOGOUT;
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (IS(response, "SEARCH"))
      {
	if (response->arguments)
	  {
	    char **strings;
	    int i;

	    strings = g_strsplit(response->arguments, " ", 0);

	    for (i = 0; strings[i]; i++)
	      if (mn_str_isnumeric(strings[i]))
		{
		  int n = atoi(strings[i]);
		  MessageInfo *info;

		  info = self_session_get_message_info(priv, n);
		  if (info)
		    info->flags |= MN_MESSAGE_NEW;
		  /*
		   * Otherwise the message is recent but not unseen,
		   * and we must ignore it (fixes #230425).
		   */
		}

	    g_strfreev(strings);
	  }

	return MN_CLIENT_SESSION_RESULT_CONTINUE;
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1367 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 800 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_fetch_uid_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1374 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_fetch_uid_cb"
{
#line 802 "src/mn-imap-mailbox.gob"
	
    GString *set;
    int result;

    g_assert(priv->messages != NULL);
    g_assert(g_hash_table_size(priv->messages) > 0);

    set = g_string_new(NULL);

    g_hash_table_foreach(priv->messages, self_build_fetch_uid_set_cb, set);

    result = self_session_write(priv, "FETCH %s UID", set->str);

    g_string_free(set, TRUE);

    return result;
  }}
#line 1395 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 820 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_build_fetch_uid_set_cb (gpointer key, gpointer value, gpointer user_data)
{
#line 1402 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::build_fetch_uid_set_cb"
{
#line 822 "src/mn-imap-mailbox.gob"
	
    MessageInfo *info = value;
    GString *set = user_data;

    if (*set->str)
      g_string_append_c(set, ',');

    g_string_append_printf(set, "%i", info->number);
  }}
#line 1415 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 832 "src/mn-imap-mailbox.gob"
static char * 
mn_imap_mailbox_parse_fetch_uid_response (const char * response)
{
#line 1422 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::parse_fetch_uid_response"
#line 832 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (response != NULL, (char * )0);
#line 1426 "mn-imap-mailbox.c"
{
#line 834 "src/mn-imap-mailbox.gob"
	
    char *start;
    char *end;

    start = mn_ascii_strcasestr_span(response, "UID ");
    if (! start)
      return NULL;

    /*
     * The UID should be the only list element, but we are tolerant
     * and allow a space in case other elements are present, eg:
     *
     *		* 1 FETCH (UID 17 OTHER_ELEMENT)
     */
    end = strpbrk(start, " )");
    if (! end || end == start)
      return NULL;

    return g_strndup(start, end - start);
  }}
#line 1449 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 855 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_fetch_uid_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1456 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_fetch_uid_cb"
{
#line 859 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    /* a failure (NO or BAD) is not fatal */
	    if (IS_OK(response) || IS_NO(response) || IS_BAD(response))
	      return STATE_FETCH;
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (mn_str_isnumeric(response->response)
	     && response->arguments
	     && mn_ascii_str_case_has_prefix(response->arguments, "FETCH "))
      {
	char *uid;

	uid = self_parse_fetch_uid_response(response->arguments);
	if (uid)
	  {
	    int n;
	    MessageInfo *info;

	    n = atoi(response->response);

	    info = self_session_get_message_info(priv, n);
	    if (info && ! info->mid)
	      {
		MNMessage *message;

		g_assert(info->message == NULL);

		/*
		 * RFC 3501 specifies that UID is a 32-bit number,
		 * but we do not need it to be one. Use a string
		 * for interoperability purposes (in case some
		 * server vendors did not read the RFC properly).
		 */
		info->mid = g_strdup_printf("%s:%s", priv->uidvalidity, uid);

		message = mn_mailbox_get_message_from_mid(priv->mailbox, info->mid);
		if (message)
		  /*
		   * We create a new instance rather than reusing
		   * the existing one since the flags might be
		   * different and a MNMessage is immutable (so we
		   * cannot change the flags of the existing
		   * message).
		   */
		  info->message = mn_g_object_clone(message,
						    MN_MESSAGE_PROP_FLAGS(info->flags),
						    NULL);
	      }

	    g_free(uid);
	  }

	return MN_CLIENT_SESSION_RESULT_CONTINUE;
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1525 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 925 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_fetch_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1532 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_fetch_cb"
{
#line 927 "src/mn-imap-mailbox.gob"
	
    GString *set;
    int result;

    g_assert(priv->messages != NULL);
    g_assert(g_hash_table_size(priv->messages) > 0);

    set = g_string_new(NULL);

    g_hash_table_foreach(priv->messages, self_build_fetch_set_cb, set);

    if (*set->str)
      result = self_session_write(priv, "FETCH %s BODY.PEEK[HEADER]", set->str);
    else
      /* all the unseen messages were cached, no message to fetch */
      result = self_session_got_messages(priv);

    g_string_free(set, TRUE);

    return result;
  }}
#line 1557 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 949 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_build_fetch_set_cb (gpointer key, gpointer value, gpointer user_data)
{
#line 1564 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::build_fetch_set_cb"
{
#line 951 "src/mn-imap-mailbox.gob"
	
    MessageInfo *info = value;
    GString *set = user_data;

    if (! info->message)
      {
	if (*set->str)
	  g_string_append_c(set, ',');

	g_string_append_printf(set, "%i", info->number);
      }
  }}
#line 1580 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 964 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_fetch_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1587 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_fetch_cb"
{
#line 968 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag)
      {
	if (HAS_CURRENT_TAG(response, priv))
	  {
	    if (IS_OK(response))
	      {
		/*
		 * Note that in previous versions we required the
		 * fetch results to include all the unseen messages,
		 * but it caused problems in some cases (#20132).
		 */

		return self_session_got_messages(priv);
	      }
	    else if (IS_NO(response) || IS_BAD(response))
	      {
		mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		return STATE_LOGOUT;
	      }
	    else
	      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	  }
      }
    else if (mn_str_isnumeric(response->response)
	     && response->arguments
	     && mn_ascii_str_case_has_prefix(response->arguments, "FETCH ")
	     && (mn_ascii_strcasestr(response->arguments, "BODY[HEADER]")
		 || mn_ascii_strcasestr(response->arguments, "BODY[HEADER "))) /* [1] */
      /*
       * [1] Non-compliant response (see RFC 3501 BNF), sent by Binc
       * IMAP and maybe others. We are tolerant.
       */
      {
	int n;
	MessageInfo *info;

	n = atoi(response->response);

	info = self_session_get_message_info(priv, n);
	if (info && ! info->message)
	  {
	    char *p;
	    int len;

	    /* we assume the header string will be in literal form */

	    p = strrchr(response->arguments, '{');
	    if (p && sscanf(p, "{%d}", &len) == 1 && len >= 0)
	      {
		gconstpointer buf;
		GError *err = NULL;

		buf = mn_client_session_read(session, len);
		if (! buf)
		  return MN_CLIENT_SESSION_RESULT_DISCONNECT;

		info->message = mn_message_new_from_buffer(priv->mailbox,
							   buf,
							   len,
							   info->mid,
							   info->flags,
							   FALSE,
							   &err);

		if (err)
		  {
		    mn_client_session_warning(session, "cannot read message %i: %s", n, err->message);
		    g_error_free(err);

		    priv->num_errors++;
		  }

		/* read end of line (after literal) */
		if (! mn_client_session_read_line(session))
		  return MN_CLIENT_SESSION_RESULT_DISCONNECT;
	      }
	    else
	      {
		mn_client_session_warning(session, "cannot retrieve message %i", n);
		priv->num_errors++;
	      }

	    return MN_CLIENT_SESSION_RESULT_CONTINUE;
	  }
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1682 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1060 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_idle_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1689 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_idle_cb"
{
#line 1063 "src/mn-imap-mailbox.gob"
	
    if (mn_mailbox_get_active(priv->mailbox))
      {
	if (priv->self->use_idle_extension == MN_IMAP_MAILBOX_USE_IDLE_NEVER)
	  mn_client_session_notice(session, _("\"Use the IDLE extension\" set to \"never\" in the mailbox properties, logging out"));
	else
	  {
	    if (self_session_has_capability(priv, "IDLE"))
	      {
		switch (priv->self->use_idle_extension)
		  {
		  case MN_IMAP_MAILBOX_USE_IDLE_AUTODETECT:
		    if (priv->server_software_supports_idle)
		      goto idle;
		    else
		      mn_client_session_notice(session, _("the remote server runs %s, not using the IDLE extension"), priv->server_software);
		    break;

		  case MN_IMAP_MAILBOX_USE_IDLE_ALWAYS:
		    if (! priv->server_software_supports_idle)
		      mn_client_session_warning(session, _("the remote server runs %s, the IDLE extension might not function properly"), priv->server_software);
		    goto idle;
		    break;

		  default:
		    g_assert_not_reached();
		  }
	      }
	    else
	      mn_client_session_notice(session, _("the remote server does not support the IDLE extension, logging out"));
	  }
      }

    return STATE_LOGOUT;

  idle:
    priv->idle_state = IDLE_STATE_PRE_IDLE;
    return self_session_write(priv, "IDLE");
  }}
#line 1732 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1103 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_idle_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1739 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_idle_cb"
{
#line 1107 "src/mn-imap-mailbox.gob"
	
    switch (priv->idle_state)
      {
      case IDLE_STATE_PRE_IDLE:
	if (response->tag)
	  {
	    if (HAS_CURRENT_TAG(response, priv))
	      {
		if (IS_NO(response) || IS_BAD(response))
		  /*
		   * The server advertised IDLE but does not actually
		   * support it.
		   *
		   * Although strictly speaking this can be considered a
		   * compliance fault, we'll be tolerant and just logout
		   * without setting an error.
		   */
		  return STATE_LOGOUT;
		else
		  return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	      }
	  }
	else if (response->continuation)
	  {
	    /* we're now in the idle loop */
	    priv->idle_state = IDLE_STATE_IDLE;
	    priv->idle_inactivity = FALSE;
	    priv->could_idle = TRUE;

	    GDK_THREADS_ENTER();
	    mn_mailbox_set_poll(priv->mailbox, FALSE);
	    gdk_flush();
	    GDK_THREADS_LEAVE();

	    return MN_CLIENT_SESSION_RESULT_CONTINUE;
	  }
	break;

      case IDLE_STATE_IDLE:
	if (response->continuation || response->tag)
	  return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;

	if (IS_BYE(response))
	  {
	    priv->idle_state = IDLE_STATE_POST_IDLE;
	    return MN_CLIENT_SESSION_RESULT_DISCONNECT; /* we'll reconnect */
	  }
	else if (response->arguments
		 && mn_str_isnumeric(response->response)
		 && (! g_ascii_strcasecmp(response->arguments, "EXISTS")
		     || ! g_ascii_strcasecmp(response->arguments, "RECENT")
		     || ! g_ascii_strcasecmp(response->arguments, "EXPUNGE")
		     || mn_ascii_str_case_has_prefix(response->arguments, "FETCH ")))
	  {
	    priv->idle_state = IDLE_STATE_POST_IDLE;
	    return mn_client_session_write(session, "DONE"); /* wake up */
	  }
	break;

      case IDLE_STATE_POST_IDLE:
	if (response->tag)
	  {
	    if (HAS_CURRENT_TAG(response, priv))
	      {
		if (IS_OK(response))
		  {
		    if (! mn_mailbox_get_active(priv->mailbox))
		      return STATE_LOGOUT;
		    else if (priv->idle_inactivity)
		      return STATE_IDLE; /* anti-inactivity, re-enter */
		    else
		      return STATE_SEARCH_UNSEEN;
		  }
		else if (IS_NO(response) || IS_BAD(response))
		  {
		    mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
		    return STATE_LOGOUT;
		  }
		else
		  return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	      }
	  }
	else if (response->continuation)
	  return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	break;

      default:
	g_assert_not_reached();
	break;
      }

    return self_default_handler(response, priv, MN_CLIENT_SESSION_ERROR_OTHER);
  }}
#line 1836 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1201 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_enter_logout_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1843 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::enter_logout_cb"
{
#line 1204 "src/mn-imap-mailbox.gob"
	
    return self_session_write(priv, "LOGOUT");
  }}
#line 1850 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1208 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_handle_logout_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1857 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::handle_logout_cb"
{
#line 1212 "src/mn-imap-mailbox.gob"
	
    if (response->continuation)
      return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
    else if (response->tag && HAS_CURRENT_TAG(response, priv))
      {
	if (IS_OK(response))
	  return MN_CLIENT_SESSION_RESULT_DISCONNECT;
	else if (IS_BAD(response))
	  return mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
	else
	  return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
    else
      return MN_CLIENT_SESSION_RESULT_CONTINUE;
  }}
#line 1876 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1228 "src/mn-imap-mailbox.gob"
static void 
___21_mn_imap_mailbox_authenticated_check (MNAuthenticatedMailbox * mailbox G_GNUC_UNUSED)
#line 1882 "mn-imap-mailbox.c"
#define PARENT_HANDLER(___mailbox) \
	{ if(MN_AUTHENTICATED_MAILBOX_CLASS(parent_class)->authenticated_check) \
		(* MN_AUTHENTICATED_MAILBOX_CLASS(parent_class)->authenticated_check)(___mailbox); }
{
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::authenticated_check"
{
#line 1230 "src/mn-imap-mailbox.gob"
	
    Self *self = SELF(mailbox);
    static const MNClientSessionState states[] = {
      { STATE_GREETING,		NULL,				self_handle_greeting_cb },
      { STATE_CAPABILITY,	self_enter_capability_cb,	self_handle_capability_cb },
#if WITH_SSL
      { STATE_STARTTLS,		self_enter_starttls_cb,		self_handle_starttls_cb },
#endif
#if WITH_SASL
      { STATE_AUTHENTICATE,	self_enter_authenticate_cb,	self_handle_authenticate_cb },
#endif
      { STATE_LOGIN,		self_enter_login_cb,		self_handle_login_cb },
      { STATE_EXAMINE,		self_enter_examine_cb,		self_handle_examine_cb },
      { STATE_SEARCH_UNSEEN,	self_enter_search_unseen_cb,	self_handle_search_unseen_cb },
      { STATE_SEARCH_RECENT,	self_enter_search_recent_cb,	self_handle_search_recent_cb },
      { STATE_FETCH_UID,	self_enter_fetch_uid_cb,	self_handle_fetch_uid_cb },
      { STATE_FETCH,		self_enter_fetch_cb,		self_handle_fetch_cb },
      { STATE_IDLE,		self_enter_idle_cb,		self_handle_idle_cb },
      { STATE_LOGOUT,		self_enter_logout_cb,		self_handle_logout_cb },

      MN_CLIENT_SESSION_STATES_END
    };
    static const MNClientSessionCallbacks callbacks = {
      mn_pi_mailbox_notice_cb,
      mn_pi_mailbox_warning_cb,
      self_response_new_cb,
      self_response_free_cb,
      self_pre_read_cb,
      self_post_read_cb,
#if WITH_SASL
      mn_pi_mailbox_sasl_get_credentials_cb,
#endif
#if WITH_SSL
      mn_pi_mailbox_ssl_trust_server_cb,
#endif
    };
    MNClientSessionPrivate priv;
    gboolean status;
    GError *err = NULL;

    PARENT_HANDLER(mailbox);

    /* check if the parent handler has disabled the mailbox */
    if (! mn_mailbox_get_poll(MN_MAILBOX(self)))
      return;

  again:
    g_clear_error(&err);

    memset(&priv, 0, sizeof(priv));
    mn_pi_mailbox_session_private_init(MN_PI_MAILBOX(self), &priv);
    priv.self = self;
    priv.server_software_supports_idle = TRUE; /* assume it does */

    status = mn_client_session_run(states,
				   &callbacks,
#if WITH_SSL
				   priv.pi_mailbox->connection_type == MN_PI_MAILBOX_CONNECTION_TYPE_SSL,
#endif
				   priv.pi_mailbox->hostname,
				   priv.pi_mailbox->runtime_port,
				   &priv,
				   &err);

    g_strfreev(priv.capabilities);
    mn_g_slist_free_deep(priv.auth_mechanisms);

    g_free(priv.uidvalidity);

    if (priv.messages)
      g_hash_table_destroy(priv.messages);

#if WITH_SASL
    g_slist_free(priv.sasl_remaining_mechanisms);
#endif

    if (priv.could_idle && mn_mailbox_get_active(priv.mailbox))
      {
	if (status)
	  goto again;
	/* some servers abruptly disconnect for inactivity */
	else if (g_error_matches(err, MN_CLIENT_SESSION_ERROR, MN_CLIENT_SESSION_ERROR_CONNECTION_LOST))
	  {
	    /* g_log() escapes unsafe and non UTF-8 characters, so this is safe */
	    mn_mailbox_notice(priv.mailbox, "%s", err->message);
	    goto again;
	  }
      }

    GDK_THREADS_ENTER();

    mn_mailbox_set_poll(MN_MAILBOX(self), TRUE);
    if (! status)
      {
	char *escaped;

	escaped = mn_utf8_escape(err->message);
	g_error_free(err);

	mn_mailbox_set_error(MN_MAILBOX(self), "%s", escaped);
	g_free(escaped);
      }

    gdk_flush();
    GDK_THREADS_LEAVE();
  }}
#line 1996 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 1337 "src/mn-imap-mailbox.gob"
static MNClientSessionResponse * 
mn_imap_mailbox_response_new_cb (MNClientSession * session, const char * input, MNClientSessionPrivate * priv)
{
#line 2004 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::response_new_cb"
{
#line 1341 "src/mn-imap-mailbox.gob"
	
    MNClientSessionResponse *response = NULL;

    /*
     * About character set handling:
     *
     * RFC 3501 section 1.2 specifies that "characters are 7-bit
     * US-ASCII unless otherwise specified", and the ABNF formal
     * syntax found in section 9 confirms it. However, we follow the
     * RFC 793 robustness principle ("be liberal in what you accept")
     * and do not require responses to be valid 7-bit US-ASCII.
     *
     * Safety:
     *   - we ensure that GTK+ will only receive UTF-8 data by
     *     escaping error messages in authenticated_check()
     *   - responses ending up in mn_mailbox_notice() need not be
     *     valid UTF-8, since g_log() escapes unsafe and non UTF-8
     *     characters
     *   - messages do not go through this function; they are handled
     *     in handle_fetch_cb() and passed to our mn-message-mime
     *     implementation, which handles character set conversions
     */

    if (! strcmp(input, "+"))
      {
	response = g_new0(MNClientSessionResponse, 1);
	response->continuation = g_strdup("");
      }
    else if (g_str_has_prefix(input, "+ "))
      {
	response = g_new0(MNClientSessionResponse, 1);
	response->continuation = g_strdup(input + 2);
      }
    else
      {
	char **tokens;

	tokens = g_strsplit(input, " ", 3);
	if (tokens[0] && tokens[1])
	  {
	    if (tokens[2] && tokens[2][0] == '[')
	      {
		char *code_start;
		char *code_end;

		code_start = tokens[2] + 1;
		code_end = strchr(code_start, ']');
		if (code_end)
		  {
		    response = g_new0(MNClientSessionResponse, 1);
		    response->code = g_strndup(code_start, code_end - code_start);
		    response->arguments = code_end[1] ? g_strdup(code_end + 2) : NULL;
		  }
	      }
	    else
	      {
		response = g_new0(MNClientSessionResponse, 1);
		response->arguments = g_strdup(tokens[2]);
	      }

	    if (response)
	      {
		response->tag = ! strcmp(tokens[0], "*") ? NULL : g_strdup(tokens[0]);
		response->response = g_strdup(tokens[1]);
	      }
	  }
	g_strfreev(tokens);
      }

    return response;
  }}
#line 2079 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1413 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_response_free_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 2086 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::response_free_cb"
{
#line 1417 "src/mn-imap-mailbox.gob"
	
    g_free(response->continuation);
    g_free(response->tag);
    g_free(response->response);
    g_free(response->code);
    g_free(response->arguments);
    g_free(response);
  }}
#line 2098 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1426 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_default_handler (MNClientSessionResponse * response, MNClientSessionPrivate * priv, int error_code_when_bye)
{
#line 2105 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::default_handler"
#line 1426 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (response != NULL, (int )0);
#line 1426 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 2111 "mn-imap-mailbox.c"
{
#line 1430 "src/mn-imap-mailbox.gob"
	
    if (! response->tag && IS_BYE(response))
      return mn_client_session_set_error_from_response(priv->session, error_code_when_bye, response->arguments);
    else
      return MN_CLIENT_SESSION_RESULT_CONTINUE;
  }}
#line 2120 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1437 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_pre_read_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 2127 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::pre_read_cb"
{
#line 1440 "src/mn-imap-mailbox.gob"
	
    if (priv->idle_state == IDLE_STATE_IDLE)
      {
	Self *self = priv->self;

	self_lock(self);

	selfp->idle_session = priv;

	/* cycle IDLE in 29 minutes, as advised by RFC 2177 */

	g_assert(priv->idle_inactivity_timeout_id == 0);
	priv->idle_inactivity_timeout_id = g_timeout_add(60 * 29 * 1000, self_idle_inactivity_timeout_cb, self);

	self_unlock(self);
      }
  }}
#line 2148 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1458 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_post_read_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 2155 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::post_read_cb"
{
#line 1461 "src/mn-imap-mailbox.gob"
	
    Self *self = priv->self;

    self_lock(self);

    if (priv->idle_state >= IDLE_STATE_IDLE)
      {
	selfp->idle_session = NULL;
	mn_source_clear(&priv->idle_inactivity_timeout_id);
      }

    self_unlock(self);
  }}
#line 2172 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1475 "src/mn-imap-mailbox.gob"
static gboolean 
mn_imap_mailbox_idle_inactivity_timeout_cb (gpointer data)
{
#line 2179 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::idle_inactivity_timeout_cb"
{
#line 1477 "src/mn-imap-mailbox.gob"
	
    Self *self = data;

    self_lock(self);

    if (selfp->idle_session)
      {
	mn_client_session_write(selfp->idle_session->session, "DONE");
	selfp->idle_session->idle_state = IDLE_STATE_POST_IDLE;
	selfp->idle_session->idle_inactivity = TRUE;
	selfp->idle_session->idle_inactivity_timeout_id = 0;
      }

    self_unlock(self);

    return FALSE;
  }}
#line 2200 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1496 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_session_write (MNClientSessionPrivate * priv, const char * format, ...)
{
#line 2207 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_write"
#line 1496 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 1496 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (format != NULL, (int )0);
#line 2213 "mn-imap-mailbox.c"
{
#line 1500 "src/mn-imap-mailbox.gob"
	
    char *command;
    int result;

    MN_STRDUP_VPRINTF(command, format);

    if (priv->numeric_tag == 1000)
      priv->numeric_tag = 0;
    sprintf(priv->tag, "a%03i", priv->numeric_tag++);

    result = mn_client_session_write(priv->session, "%s %s", priv->tag, command);
    g_free(command);

    return result;
  }}
#line 2231 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1516 "src/mn-imap-mailbox.gob"
static gboolean 
mn_imap_mailbox_session_handle_capability_code (MNClientSessionPrivate * priv, MNClientSessionResponse * response)
{
#line 2238 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_handle_capability_code"
#line 1516 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (gboolean )0);
#line 1516 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (response != NULL, (gboolean )0);
#line 2244 "mn-imap-mailbox.c"
{
#line 1519 "src/mn-imap-mailbox.gob"
	
    if (response->code)
      {
	if (! g_ascii_strcasecmp(response->code, "CAPABILITY"))
	  {
	    self_session_parse_capabilities(priv, NULL);
	    return TRUE;
	  }
	else if (mn_ascii_str_case_has_prefix(response->code, "CAPABILITY "))
	  {
	    self_session_parse_capabilities(priv, response->code + 11);
	    return TRUE;
	  }
      }

    return FALSE;
  }}
#line 2264 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1537 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_session_parse_capabilities (MNClientSessionPrivate * priv, const char * capabilities)
{
#line 2271 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_parse_capabilities"
#line 1537 "src/mn-imap-mailbox.gob"
	g_return_if_fail (priv != NULL);
#line 2275 "mn-imap-mailbox.c"
{
#line 1540 "src/mn-imap-mailbox.gob"
	
    g_strfreev(priv->capabilities);
    priv->capabilities = NULL;

    mn_g_slist_clear_deep(&priv->auth_mechanisms);

#if WITH_SASL
    mn_g_slist_clear(&priv->sasl_remaining_mechanisms);
#endif

    if (capabilities)
      {
	int i;

	priv->capabilities = g_strsplit(capabilities, " ", 0);

	for (i = 0; priv->capabilities[i]; i++)
	  if (g_str_has_prefix(priv->capabilities[i], "AUTH="))
	    priv->auth_mechanisms = g_slist_append(priv->auth_mechanisms, g_strdup(priv->capabilities[i] + 5));
      }
    else
      priv->capabilities = g_new0(char *, 1);
  }}
#line 2301 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1564 "src/mn-imap-mailbox.gob"
static gboolean 
mn_imap_mailbox_session_has_capability (MNClientSessionPrivate * priv, const char * capability)
{
#line 2308 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_has_capability"
#line 1564 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (gboolean )0);
#line 1564 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (capability != NULL, (gboolean )0);
#line 2314 "mn-imap-mailbox.c"
{
#line 1567 "src/mn-imap-mailbox.gob"
	
    int i;

    g_return_val_if_fail(priv->capabilities != NULL, FALSE);

    for (i = 0; priv->capabilities[i]; i++)
      if (! g_ascii_strcasecmp(priv->capabilities[i], capability))
	return TRUE;

    return FALSE;
  }}
#line 2328 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1579 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_session_after_capability (MNClientSessionPrivate * priv)
{
#line 2335 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_after_capability"
#line 1579 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 2339 "mn-imap-mailbox.c"
{
#line 1581 "src/mn-imap-mailbox.gob"
	
    if (priv->authenticated)
      return STATE_EXAMINE;
    else
      {
#if WITH_SSL
	if (priv->pi_mailbox->connection_type == MN_PI_MAILBOX_CONNECTION_TYPE_INBAND_SSL
	    && ! priv->starttls_completed)
	  {
	    if (self_session_has_capability(priv, "STARTTLS"))
	      return STATE_STARTTLS;
	    else
	      {
		mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("server does not support in-band SSL/TLS"));
		return STATE_LOGOUT;
	      }
	  }
#endif /* WITH_SSL */
	return self_session_authenticate(priv);
      }
  }}
#line 2363 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1603 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_session_authenticate (MNClientSessionPrivate * priv)
{
#line 2370 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_authenticate"
#line 1603 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 2374 "mn-imap-mailbox.c"
{
#line 1605 "src/mn-imap-mailbox.gob"
	
#if WITH_SASL
    g_slist_free(priv->sasl_remaining_mechanisms);
    priv->sasl_remaining_mechanisms = g_slist_copy(priv->auth_mechanisms);
#endif /* WITH_SASL */

    if (priv->pi_mailbox->authmech)
      {
	if (*priv->pi_mailbox->authmech != '+')
	  {
#if WITH_SASL
	    return STATE_AUTHENTICATE;
#else
	    mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("a SASL authentication mechanism was selected but SASL support has not been compiled in"));
	    return STATE_LOGOUT;
#endif /* WITH_SASL */
	  }
	else
	  {
	    if (! strcmp(priv->pi_mailbox->authmech, "+LOGIN"))
	      return STATE_LOGIN;
	    else
	      {
		mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("unknown authentication mechanism \"%s\""), priv->pi_mailbox->authmech);
		return STATE_LOGOUT;
	      }
	  }
      }
    else
      {
#if WITH_SASL
	if (priv->sasl_remaining_mechanisms)
	  return STATE_AUTHENTICATE;
#endif /* WITH_SASL */
	return STATE_LOGIN;
      }
  }}
#line 2414 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1643 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_session_authenticate_fallback (MNClientSessionPrivate * priv, gboolean tried_login)
{
#line 2421 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_authenticate_fallback"
#line 1643 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 2425 "mn-imap-mailbox.c"
{
#line 1646 "src/mn-imap-mailbox.gob"
	
    if (! priv->pi_mailbox->authmech)
      {
#if WITH_SASL
	if (priv->sasl_mechanism)
	  {
	    GSList *elem;

	    elem = mn_g_str_slist_find(priv->sasl_remaining_mechanisms, priv->sasl_mechanism);
	    if (elem)
	      {
		priv->sasl_remaining_mechanisms = g_slist_delete_link(priv->sasl_remaining_mechanisms, elem);
		if (priv->sasl_remaining_mechanisms)
		  {
		    mn_client_session_notice(priv->session, _("disabling mechanism \"%s\" and retrying SASL authentication"), priv->sasl_mechanism);
		    return STATE_AUTHENTICATE;
		  }
	      }
	  }

	/* SASL is not needed anymore, save some memory */
	mn_client_session_sasl_dispose(priv->session);
#endif /* WITH_SASL */

	if (! tried_login)
	  {
	    mn_client_session_notice(priv->session, _("falling back to IMAP LOGIN authentication"));
	    return STATE_LOGIN;
	  }
      }

    if (priv->auth_mailbox->auth_prompted)
      {
	mn_authenticated_mailbox_auth_failed(priv->auth_mailbox);
	return self_session_authenticate(priv);
      }
    else
      {
	mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("authentication failed"));
	return STATE_LOGOUT;
      }
  }}
#line 2470 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1689 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_session_detect_imapd (MNClientSession * session, MNClientSessionResponse * greeting_response, MNClientSessionPrivate * priv)
{
#line 2477 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_detect_imapd"
#line 1689 "src/mn-imap-mailbox.gob"
	g_return_if_fail (session != NULL);
#line 1689 "src/mn-imap-mailbox.gob"
	g_return_if_fail (greeting_response != NULL);
#line 1689 "src/mn-imap-mailbox.gob"
	g_return_if_fail (priv != NULL);
#line 2485 "mn-imap-mailbox.c"
{
#line 1693 "src/mn-imap-mailbox.gob"
	
    if (greeting_response->arguments)
      {
	char *str;

	/*
	 * Try to detect UW imapd by looking for " IMAP4rev1 YEAR."
	 */

	if ((str = mn_strstr_span(greeting_response->arguments, " IMAP4rev1 "))
	    && strspn(str, "0123456789") == 4
	    && str[4] == '.')
	  {
	    priv->server_software = "UW imapd";
	    priv->server_software_supports_idle = FALSE;
	    return;
	  }
      }
  }}
#line 2507 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1713 "src/mn-imap-mailbox.gob"
static int 
mn_imap_mailbox_session_got_messages (MNClientSessionPrivate * priv)
{
#line 2514 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_got_messages"
#line 1713 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 2518 "mn-imap-mailbox.c"
{
#line 1715 "src/mn-imap-mailbox.gob"
	
    GSList *messages = NULL;

    g_hash_table_foreach(priv->messages, self_get_messages_list_cb, &messages);

    GDK_THREADS_ENTER();

    mn_mailbox_set_messages(priv->mailbox, messages);

    if (priv->num_errors == 0)
      mn_mailbox_set_error(priv->mailbox, NULL);
    else
      mn_mailbox_set_error(priv->mailbox,
			   ngettext("cannot retrieve %i message",
				    "cannot retrieve %i messages",
				    priv->num_errors),
			   priv->num_errors);

    /*
     * In authenticated_check(), we do not hold the GDK lock while
     * destroying the messages hash table. We have just exposed the
     * messages to other threads through our mn_mailbox_set_messages()
     * call, so destroy the hash table here, while we hold the GDK
     * lock.
     */
    g_hash_table_destroy(priv->messages);
    priv->messages = NULL;

    gdk_flush();
    GDK_THREADS_LEAVE();

    g_slist_free(messages);

    return STATE_IDLE;
  }}
#line 2556 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1751 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_get_messages_list_cb (gpointer key, gpointer value, gpointer user_data)
{
#line 2563 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::get_messages_list_cb"
{
#line 1753 "src/mn-imap-mailbox.gob"
	
    MessageInfo *info = value;
    GSList **list = user_data;

    if (info->message)
      *list = g_slist_prepend(*list, info->message);
  }}
#line 2574 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1761 "src/mn-imap-mailbox.gob"
static MessageInfo * 
mn_imap_mailbox_session_get_message_info (MNClientSessionPrivate * priv, int number)
{
#line 2581 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_get_message_info"
#line 1761 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (MessageInfo * )0);
#line 2585 "mn-imap-mailbox.c"
{
#line 1764 "src/mn-imap-mailbox.gob"
	
    return g_hash_table_lookup(priv->messages, GINT_TO_POINTER(number));
  }}
#line 2591 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1768 "src/mn-imap-mailbox.gob"
static MessageInfo * 
mn_imap_mailbox_session_ensure_message_info (MNClientSessionPrivate * priv, int number)
{
#line 2598 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::session_ensure_message_info"
#line 1768 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (MessageInfo * )0);
#line 2602 "mn-imap-mailbox.c"
{
#line 1771 "src/mn-imap-mailbox.gob"
	
    MessageInfo *info;

    info = self_session_get_message_info(priv, number);
    if (! info)
      {
	info = self_message_info_new(number);
	g_hash_table_insert(priv->messages, GINT_TO_POINTER(number), info);
      }

    return info;
  }}
#line 2617 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1784 "src/mn-imap-mailbox.gob"
static MessageInfo * 
mn_imap_mailbox_message_info_new (int number)
{
#line 2624 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::message_info_new"
{
#line 1786 "src/mn-imap-mailbox.gob"
	
    MessageInfo *info;

    info = g_new0(MessageInfo, 1);
    info->number = number;

    return info;
  }}
#line 2636 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1795 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_message_info_free (MessageInfo * info)
{
#line 2643 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::message_info_free"
#line 1795 "src/mn-imap-mailbox.gob"
	g_return_if_fail (info != NULL);
#line 2647 "mn-imap-mailbox.c"
{
#line 1797 "src/mn-imap-mailbox.gob"
	
    if (info->message)
      g_object_unref(info->message);
    g_free(info->mid);
    g_free(info);
  }}
#line 2656 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

/**
 * mn_imap_mailbox_quote:
 * @str: the string to quote
 *
 * Quotes a string using RFC 3501 BNF rules.
 *
 * Return value: the quoted string.
 **/
#line 1812 "src/mn-imap-mailbox.gob"
static char * 
mn_imap_mailbox_quote (const char * str)
{
#line 2671 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::quote"
#line 1812 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (str != NULL, (char * )0);
#line 2675 "mn-imap-mailbox.c"
{
#line 1814 "src/mn-imap-mailbox.gob"
	
    GString *quoted;
    int i;

    quoted = g_string_new("\"");
    for (i = 0; str[i]; i++)
      if (str[i] == '"' || str[i] == '\\') /* quoted-specials in BNF */
	g_string_append_printf(quoted, "\\%c", str[i]);
      else
	g_string_append_c(quoted, str[i]);
    g_string_append_c(quoted, '"');

    return g_string_free(quoted, FALSE);
  }}
#line 2692 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

/**
 * mn_imap_mailbox_utf8_to_imap_utf7:
 * @str: the UTF-8 string to convert to modified UTF-7
 *
 * Converts a string from UTF-8 to modified UTF-7 as defined by RFC 3501.
 *
 * Return value: the string converted to modified UTF-7.
 **/
#line 1837 "src/mn-imap-mailbox.gob"
static char * 
mn_imap_mailbox_utf8_to_imap_utf7 (const char * str)
{
#line 2707 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::utf8_to_imap_utf7"
#line 1837 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (str != NULL, (char * )0);
#line 2711 "mn-imap-mailbox.c"
{
#line 1839 "src/mn-imap-mailbox.gob"
	
    gunichar c;
    guint32 x, v = 0;
    int state = 0;
    GString *out;
    int i = 0;

    /*
     * Taken from the Ximian Evolution sources (camel-utf8.c) and
     * edited for style.
     */

    out = g_string_new(NULL);

    while ((c = g_utf8_get_char(str)))
      {
	if (c >= 0x20 && c <= 0x7e)
	  {
	    if (state == 1)
	      {
		self_imap_utf7_closeb64(out, v, i);
		state = 0;
		i = 0;
	      }
	    if (c == '&')
	      g_string_append(out, "&-");
	    else
	      g_string_append_c(out, c);
	  }
	else
	  {
	    if (state == 0)
	      {
		g_string_append_c(out, '&');
		state = 1;
	      }

	    v = (v << 16) | c;
	    i += 16;

	    while (i >= 6)
	      {
		x = (v >> (i - 6)) & 0x3f;
		g_string_append_c(out, utf7_alphabet[x]);
		i -= 6;
	      }
	  }

	str = g_utf8_next_char(str);
      }

    if (state == 1)
      self_imap_utf7_closeb64(out, v, i);

    return g_string_free(out, FALSE);
  }}
#line 2770 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1896 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_imap_utf7_closeb64 (GString * out, guint32 v, guint32 i)
{
#line 2777 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::imap_utf7_closeb64"
#line 1896 "src/mn-imap-mailbox.gob"
	g_return_if_fail (out != NULL);
#line 2781 "mn-imap-mailbox.c"
{
#line 1898 "src/mn-imap-mailbox.gob"
	
    /*
     * Taken from the Ximian Evolution sources (camel-utf8.c) and
     * edited for style.
     */

    if (i > 0)
      {
	guint32 x;

	x = (v << (6 - i)) & 0x3f;
	g_string_append_c(out, utf7_alphabet[x]);
      }

    g_string_append_c(out, '-');
  }}
#line 2800 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1915 "src/mn-imap-mailbox.gob"
char * 
mn_imap_mailbox_build_name (const char * username, const char * server, const char * mailbox)
{
#line 2807 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::build_name"
#line 1915 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (username != NULL, (char * )0);
#line 1915 "src/mn-imap-mailbox.gob"
	g_return_val_if_fail (server != NULL, (char * )0);
#line 2813 "mn-imap-mailbox.c"
{
#line 1919 "src/mn-imap-mailbox.gob"
	
    GString *name;

    name = g_string_new(NULL);

    g_string_append_printf(name, "%s@%s", username, server);

    if (mailbox && mn_utf8_strcasecmp(mailbox, "INBOX"))
      g_string_append_printf(name, "/%s", mailbox);

    return g_string_free(name, FALSE);
  }}
#line 2828 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1932 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_lock (MNIMAPMailbox * self)
{
#line 2835 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::lock"
#line 1932 "src/mn-imap-mailbox.gob"
	g_return_if_fail (self != NULL);
#line 1932 "src/mn-imap-mailbox.gob"
	g_return_if_fail (MN_IS_IMAP_MAILBOX (self));
#line 2841 "mn-imap-mailbox.c"
{
#line 1934 "src/mn-imap-mailbox.gob"
	
    g_mutex_lock(selfp->mutex);
  }}
#line 2847 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__

#line 1938 "src/mn-imap-mailbox.gob"
static void 
mn_imap_mailbox_unlock (MNIMAPMailbox * self)
{
#line 2854 "mn-imap-mailbox.c"
#define __GOB_FUNCTION__ "MN:IMAP:Mailbox::unlock"
#line 1938 "src/mn-imap-mailbox.gob"
	g_return_if_fail (self != NULL);
#line 1938 "src/mn-imap-mailbox.gob"
	g_return_if_fail (MN_IS_IMAP_MAILBOX (self));
#line 2860 "mn-imap-mailbox.c"
{
#line 1940 "src/mn-imap-mailbox.gob"
	
    g_mutex_unlock(selfp->mutex);
  }}
#line 2866 "mn-imap-mailbox.c"
#undef __GOB_FUNCTION__
