/* 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-pop3-mailbox.h"

#include "mn-pop3-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 38 "src/mn-pop3-mailbox.gob"

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <glib/gi18n.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#if WITH_SASL
#include <sasl/saslutil.h>
#endif /* WITH_SASL */
#include "mn-mailbox-private.h"
#include "mn-authenticated-mailbox-private.h"
#include "mn-pi-mailbox-private.h"
#include "mn-client-session.h"
#include "mn-util.h"
#include "mn-md5.h"
#include "mn-message-mime.h"

enum
{
  STATE_GREETING = MN_CLIENT_SESSION_INITIAL_STATE,
  STATE_CAPA,
#if WITH_SSL
  STATE_STLS,
#endif
#if WITH_SASL
  STATE_AUTH,
#endif
  STATE_APOP,
  STATE_USER,
  STATE_PASS,
  STATE_LIST,
  STATE_UIDL,
  STATE_RETR_TOP,
  STATE_QUIT
};

struct _MNClientSessionPrivate
{
  MN_PI_MAILBOX_SESSION_PRIVATE;
  MNPOP3Mailbox			*self;

  gboolean			in_list;
  gboolean			in_retr_top;

  char				*apop_timestamp;
  GSList			*auth_mechanisms;

  gboolean			top_supported;
  gboolean			uidl_supported;

#if WITH_SSL
  gboolean			stls_supported;
  gboolean			stls_completed;
#endif

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

  gboolean			authenticated;

  gboolean			login_delay_user;

  int				num_errors;
  GSList			*messages;
  GSList			*message_iter;
  GString			*message_buffer;
};

typedef enum
{
  RESPONSE_OK,
  RESPONSE_ERR,
  RESPONSE_LIST_ITEM,
  RESPONSE_LIST_END,
  RESPONSE_CONTINUATION
} ResponseType;

struct _MNClientSessionResponse
{
  ResponseType	type;
  char		*arguments;
};

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

int mn_pop3_mailbox_default_ports[MN_PI_MAILBOX_N_CONNECTION_TYPES] = { 110, 110, 995 };

#line 122 "mn-pop3-mailbox.c"
/* self casting macros */
#define SELF(x) MN_POP3_MAILBOX(x)
#define SELF_CONST(x) MN_POP3_MAILBOX_CONST(x)
#define IS_SELF(x) MN_IS_POP3_MAILBOX(x)
#define TYPE_SELF MN_TYPE_POP3_MAILBOX
#define SELF_CLASS(x) MN_POP3_MAILBOX_CLASS(x)

#define SELF_GET_CLASS(x) MN_POP3_MAILBOX_GET_CLASS(x)

/* self typedefs */
typedef MNPOP3Mailbox Self;
typedef MNPOP3MailboxClass SelfClass;

/* here are local prototypes */
#line 141 "src/mn-pop3-mailbox.gob"
static void mn_pop3_mailbox_class_init (MNPOP3MailboxClass * class);
#line 139 "mn-pop3-mailbox.c"
#line 147 "src/mn-pop3-mailbox.gob"
static void mn_pop3_mailbox_init (MNPOP3Mailbox * self);
#line 142 "mn-pop3-mailbox.c"
#line 152 "src/mn-pop3-mailbox.gob"
static void ___3_mn_pop3_mailbox_seal (MNMailbox * mailbox);
#line 145 "mn-pop3-mailbox.c"
#line 174 "src/mn-pop3-mailbox.gob"
static MNMailbox * ___4_mn_pop3_mailbox_parse_uri (MNMailbox * dummy, const char * uri);
#line 148 "mn-pop3-mailbox.c"
#line 231 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_greeting_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 151 "mn-pop3-mailbox.c"
#line 265 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_capa_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 154 "mn-pop3-mailbox.c"
#line 272 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_capa_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 157 "mn-pop3-mailbox.c"
#line 368 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_stls_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 160 "mn-pop3-mailbox.c"
#line 380 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_stls_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 163 "mn-pop3-mailbox.c"
#line 415 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_auth_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 166 "mn-pop3-mailbox.c"
#line 473 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_auth_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 169 "mn-pop3-mailbox.c"
#line 519 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_apop_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 172 "mn-pop3-mailbox.c"
#line 541 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_apop_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 175 "mn-pop3-mailbox.c"
#line 559 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_user_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 178 "mn-pop3-mailbox.c"
#line 566 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_user_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 181 "mn-pop3-mailbox.c"
#line 585 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_pass_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 184 "mn-pop3-mailbox.c"
#line 595 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_pass_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 187 "mn-pop3-mailbox.c"
#line 613 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_list_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 190 "mn-pop3-mailbox.c"
#line 620 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_list_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 193 "mn-pop3-mailbox.c"
#line 655 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_uidl_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 196 "mn-pop3-mailbox.c"
#line 662 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_uidl_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 199 "mn-pop3-mailbox.c"
#line 715 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_retr_top_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 202 "mn-pop3-mailbox.c"
#line 766 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_retr_top_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 205 "mn-pop3-mailbox.c"
#line 835 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_enter_quit_cb (MNClientSession * session, MNClientSessionPrivate * priv);
#line 208 "mn-pop3-mailbox.c"
#line 842 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_handle_quit_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 211 "mn-pop3-mailbox.c"
#line 860 "src/mn-pop3-mailbox.gob"
static void ___1a_mn_pop3_mailbox_authenticated_check (MNAuthenticatedMailbox * mailbox);
#line 214 "mn-pop3-mailbox.c"
#line 972 "src/mn-pop3-mailbox.gob"
static MNClientSessionResponse * mn_pop3_mailbox_response_new_cb (MNClientSession * session, const char * input, MNClientSessionPrivate * priv);
#line 217 "mn-pop3-mailbox.c"
#line 1056 "src/mn-pop3-mailbox.gob"
static void mn_pop3_mailbox_response_free_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv);
#line 220 "mn-pop3-mailbox.c"
#line 1065 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_session_authenticate (MNClientSessionPrivate * priv);
#line 223 "mn-pop3-mailbox.c"
#line 1118 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_session_authenticate_fallback (MNClientSessionPrivate * priv, gboolean tried_apop, gboolean tried_pass);
#line 226 "mn-pop3-mailbox.c"
#line 1170 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_session_authenticated (MNClientSessionPrivate * priv);
#line 229 "mn-pop3-mailbox.c"
#line 1199 "src/mn-pop3-mailbox.gob"
static void mn_pop3_mailbox_session_handle_list_response (MNClientSessionPrivate * priv, MNClientSessionResponse * response, gboolean in_retr_top);
#line 232 "mn-pop3-mailbox.c"
#line 1221 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_session_enter_list_or_uidl (MNClientSessionPrivate * priv);
#line 235 "mn-pop3-mailbox.c"
#line 1230 "src/mn-pop3-mailbox.gob"
static int mn_pop3_mailbox_session_enter_retr_top (MNClientSessionPrivate * priv);
#line 238 "mn-pop3-mailbox.c"
#line 1238 "src/mn-pop3-mailbox.gob"
static MessageInfo * mn_pop3_mailbox_session_message_iter_get_message_info (MNClientSessionPrivate * priv);
#line 241 "mn-pop3-mailbox.c"
#line 1252 "src/mn-pop3-mailbox.gob"
static gboolean mn_pop3_mailbox_parse_uidl_list_item (const char * item, int * number, char ** uid);
#line 244 "mn-pop3-mailbox.c"
#line 1272 "src/mn-pop3-mailbox.gob"
static MessageInfo * mn_pop3_mailbox_message_info_new (int number);
#line 247 "mn-pop3-mailbox.c"
#line 1283 "src/mn-pop3-mailbox.gob"
static void mn_pop3_mailbox_message_info_free (MessageInfo * info);
#line 250 "mn-pop3-mailbox.c"

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

/* Short form macros */
#define self_handle_greeting_cb mn_pop3_mailbox_handle_greeting_cb
#define self_enter_capa_cb mn_pop3_mailbox_enter_capa_cb
#define self_handle_capa_cb mn_pop3_mailbox_handle_capa_cb
#define self_enter_stls_cb mn_pop3_mailbox_enter_stls_cb
#define self_handle_stls_cb mn_pop3_mailbox_handle_stls_cb
#define self_enter_auth_cb mn_pop3_mailbox_enter_auth_cb
#define self_handle_auth_cb mn_pop3_mailbox_handle_auth_cb
#define self_enter_apop_cb mn_pop3_mailbox_enter_apop_cb
#define self_handle_apop_cb mn_pop3_mailbox_handle_apop_cb
#define self_enter_user_cb mn_pop3_mailbox_enter_user_cb
#define self_handle_user_cb mn_pop3_mailbox_handle_user_cb
#define self_enter_pass_cb mn_pop3_mailbox_enter_pass_cb
#define self_handle_pass_cb mn_pop3_mailbox_handle_pass_cb
#define self_enter_list_cb mn_pop3_mailbox_enter_list_cb
#define self_handle_list_cb mn_pop3_mailbox_handle_list_cb
#define self_enter_uidl_cb mn_pop3_mailbox_enter_uidl_cb
#define self_handle_uidl_cb mn_pop3_mailbox_handle_uidl_cb
#define self_enter_retr_top_cb mn_pop3_mailbox_enter_retr_top_cb
#define self_handle_retr_top_cb mn_pop3_mailbox_handle_retr_top_cb
#define self_enter_quit_cb mn_pop3_mailbox_enter_quit_cb
#define self_handle_quit_cb mn_pop3_mailbox_handle_quit_cb
#define self_response_new_cb mn_pop3_mailbox_response_new_cb
#define self_response_free_cb mn_pop3_mailbox_response_free_cb
#define self_session_authenticate mn_pop3_mailbox_session_authenticate
#define self_session_authenticate_fallback mn_pop3_mailbox_session_authenticate_fallback
#define self_session_authenticated mn_pop3_mailbox_session_authenticated
#define self_session_handle_list_response mn_pop3_mailbox_session_handle_list_response
#define self_session_enter_list_or_uidl mn_pop3_mailbox_session_enter_list_or_uidl
#define self_session_enter_retr_top mn_pop3_mailbox_session_enter_retr_top
#define self_session_message_iter_get_message_info mn_pop3_mailbox_session_message_iter_get_message_info
#define self_parse_uidl_list_item mn_pop3_mailbox_parse_uidl_list_item
#define self_message_info_new mn_pop3_mailbox_message_info_new
#define self_message_info_free mn_pop3_mailbox_message_info_free
#define self_build_name mn_pop3_mailbox_build_name
GType
mn_pop3_mailbox_get_type (void)
{
	static GType type = 0;

	if ___GOB_UNLIKELY(type == 0) {
		static const GTypeInfo info = {
			sizeof (MNPOP3MailboxClass),
			(GBaseInitFunc) NULL,
			(GBaseFinalizeFunc) NULL,
			(GClassInitFunc) mn_pop3_mailbox_class_init,
			(GClassFinalizeFunc) NULL,
			NULL /* class_data */,
			sizeof (MNPOP3Mailbox),
			0 /* n_preallocs */,
			(GInstanceInitFunc) mn_pop3_mailbox_init,
			NULL
		};

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

	return type;
}

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

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


static void
___finalize(GObject *obj_self)
{
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::finalize"
	MNPOP3Mailbox *self G_GNUC_UNUSED = MN_POP3_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 139 "src/mn-pop3-mailbox.gob"
	if(self->_priv->authentication_timer) { g_timer_destroy ((gpointer) self->_priv->authentication_timer); self->_priv->authentication_timer = NULL; }
#line 343 "mn-pop3-mailbox.c"
}
#undef __GOB_FUNCTION__

#line 141 "src/mn-pop3-mailbox.gob"
static void 
mn_pop3_mailbox_class_init (MNPOP3MailboxClass * class G_GNUC_UNUSED)
{
#line 351 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3: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(MNPOP3MailboxPrivate));

	parent_class = g_type_class_ref (MN_TYPE_PI_MAILBOX);

#line 152 "src/mn-pop3-mailbox.gob"
	mn_mailbox_class->seal = ___3_mn_pop3_mailbox_seal;
#line 174 "src/mn-pop3-mailbox.gob"
	mn_mailbox_class->parse_uri = ___4_mn_pop3_mailbox_parse_uri;
#line 860 "src/mn-pop3-mailbox.gob"
	mn_authenticated_mailbox_class->authenticated_check = ___1a_mn_pop3_mailbox_authenticated_check;
#line 367 "mn-pop3-mailbox.c"
	g_object_class->finalize = ___finalize;
 {
#line 142 "src/mn-pop3-mailbox.gob"

    MN_MAILBOX_CLASS(class)->type = "pop3";
    MN_PI_MAILBOX_CLASS(class)->default_ports = mn_pop3_mailbox_default_ports;
  
#line 375 "mn-pop3-mailbox.c"
 }
}
#undef __GOB_FUNCTION__
#line 147 "src/mn-pop3-mailbox.gob"
static void 
mn_pop3_mailbox_init (MNPOP3Mailbox * self G_GNUC_UNUSED)
{
#line 383 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::init"
	self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self,MN_TYPE_POP3_MAILBOX,MNPOP3MailboxPrivate);
 {
#line 148 "src/mn-pop3-mailbox.gob"

    mn_mailbox_set_format(MN_MAILBOX(self), "POP3");
  
#line 391 "mn-pop3-mailbox.c"
 }
}
#undef __GOB_FUNCTION__



#line 152 "src/mn-pop3-mailbox.gob"
static void 
___3_mn_pop3_mailbox_seal (MNMailbox * mailbox G_GNUC_UNUSED)
#line 401 "mn-pop3-mailbox.c"
#define PARENT_HANDLER(___mailbox) \
	{ if(MN_MAILBOX_CLASS(parent_class)->seal) \
		(* MN_MAILBOX_CLASS(parent_class)->seal)(___mailbox); }
{
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::seal"
{
#line 154 "src/mn-pop3-mailbox.gob"
	
    MNAuthenticatedMailbox *auth_mailbox = MN_AUTHENTICATED_MAILBOX(mailbox);

    PARENT_HANDLER(mailbox);

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

#if WITH_SSL
    if (MN_PI_MAILBOX(mailbox)->connection_type == MN_PI_MAILBOX_CONNECTION_TYPE_SSL)
      auth_mailbox->keyring_protocol = g_strdup("pop3s");
    else
#endif
      auth_mailbox->keyring_protocol = g_strdup("pop3");
  }}
#line 425 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 174 "src/mn-pop3-mailbox.gob"
static MNMailbox * 
___4_mn_pop3_mailbox_parse_uri (MNMailbox * dummy G_GNUC_UNUSED, const char * uri)
#line 432 "mn-pop3-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:POP3:Mailbox::parse_uri"
{
#line 176 "src/mn-pop3-mailbox.gob"
	
    int len;
    int buflen;
    char *username = NULL;
    char *authmech = NULL;
    char *hostname;
    int port;
    MNMailbox *mailbox;

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

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

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

      if (strcmp(scheme_buf, "pop"))
	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(location_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);
    }

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

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

    return mailbox;
  }}
#line 495 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 231 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_greeting_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 503 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_greeting_cb"
{
#line 235 "src/mn-pop3-mailbox.gob"
	
    priv->session = session;

    switch (response->type)
      {
      case RESPONSE_OK:
	if (response->arguments)
	  {
	    char *timestamp;

	    timestamp = strchr(response->arguments, '<');
	    if (timestamp)
	      {
		char *timestamp_end;

		timestamp_end = strchr(timestamp, '>');
		if (timestamp_end)
		  priv->apop_timestamp = g_strndup(timestamp, timestamp_end - timestamp + 1);
	      }
	  }
	return STATE_CAPA;

      case RESPONSE_ERR:
	return mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 536 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 265 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_capa_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 543 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_capa_cb"
{
#line 268 "src/mn-pop3-mailbox.gob"
	
    return mn_client_session_write(session, "CAPA");
  }}
#line 550 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 272 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_capa_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 557 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_capa_cb"
{
#line 276 "src/mn-pop3-mailbox.gob"
	
    self_session_handle_list_response(priv, response, FALSE);

    switch (response->type)
      {
      case RESPONSE_OK:
	mn_g_slist_clear_deep(&priv->auth_mechanisms);
#if WITH_SASL
	mn_g_slist_clear(&priv->sasl_remaining_mechanisms);
#endif
	priv->top_supported = FALSE;
	priv->uidl_supported = FALSE;
	priv->self->_priv->login_delay = 0;
	priv->login_delay_user = FALSE;
#if WITH_SSL
	priv->stls_supported = FALSE;
#endif

	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      case RESPONSE_ERR:
      case RESPONSE_LIST_END:
	if (priv->authenticated)
	  return self_session_enter_list_or_uidl(priv);

#if WITH_SSL
	if (priv->pi_mailbox->connection_type == MN_PI_MAILBOX_CONNECTION_TYPE_INBAND_SSL
	    && ! priv->stls_completed)
	  {
	    if (priv->stls_supported)
	      return STATE_STLS;
	    else
	      {
		mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("server does not support in-band SSL/TLS"));
		return STATE_QUIT;
	      }
	  }
	else
#endif /* WITH_SSL */
	  return self_session_authenticate(priv);

      case RESPONSE_LIST_ITEM:
	{
	  char **tokens;
	  gboolean login_delay_error = FALSE;

	  tokens = g_strsplit(response->arguments, " ", 0);
	  if (tokens[0])
	    {
	      if (! strcmp(tokens[0], "SASL"))
		{
		  int i;

		  for (i = 1; tokens[i]; i++)
		    priv->auth_mechanisms = g_slist_append(priv->auth_mechanisms, g_strdup(tokens[i]));
		}
	      else if (! strcmp(tokens[0], "TOP"))
		priv->top_supported = TRUE;
	      else if (! strcmp(tokens[0], "UIDL"))
		priv->uidl_supported = TRUE;
#if WITH_SSL
	      else if (! strcmp(tokens[0], "STLS"))
		priv->stls_supported = TRUE;
#endif /* WITH_SSL */
	      else if (! strcmp(tokens[0], "LOGIN-DELAY"))
		{
		  if (tokens[1] && mn_str_isnumeric(tokens[1])
		      && (! tokens[2]
			  || (! tokens[3]
			      && ! priv->authenticated
			      && ! strcmp(tokens[2], "USER"))))
		    {
		      priv->self->_priv->login_delay = atoi(tokens[1]);
		      if (tokens[2])
			priv->login_delay_user = TRUE;
		    }
		  else
		    login_delay_error = TRUE;
		}
	    }
	  g_strfreev(tokens);

	  if (login_delay_error)
	    return mn_client_session_set_error(session, MN_CLIENT_SESSION_ERROR_OTHER, _("invalid arguments for the LOGIN-DELAY capability"));
	}
	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 652 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 368 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_stls_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 659 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_stls_cb"
{
#line 371 "src/mn-pop3-mailbox.gob"
	
#if WITH_SSL
    return mn_client_session_write(session, "STLS");
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SSL */
  }}
#line 671 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 380 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_stls_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 678 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_stls_cb"
{
#line 384 "src/mn-pop3-mailbox.gob"
	
#if WITH_SSL
    switch (response->type)
      {
      case RESPONSE_OK:
	priv->stls_completed = TRUE;
	return mn_client_session_enable_ssl(session)
	  ? STATE_CAPA /* [1] */
	  : MN_CLIENT_SESSION_RESULT_DISCONNECT;

	/*
	 * [1] RFC 2595 4:
	 *
	 * "Once TLS has been started, the client MUST discard cached
	 * information about server capabilities and SHOULD re-issue
	 * the CAPA command."
	 */

      case RESPONSE_ERR:
	mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
	return STATE_QUIT;

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SSL */
  }}
#line 712 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 415 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_auth_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 719 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_auth_cb"
{
#line 418 "src/mn-pop3-mailbox.gob"
	
#if WITH_SASL
    /*
     * RFC 2449 6.3 specifies that POP3 supports the initial client
     * response feature of SASL.
     */
    const char *initial_clientout = NULL;
    unsigned int initial_clientoutlen = 0;

    priv->sasl_mechanism = NULL;

    if (mn_client_session_sasl_authentication_start(priv->session,
						    "pop",
						    priv->sasl_remaining_mechanisms,
						    priv->pi_mailbox->authmech,
						    &priv->sasl_mechanism,
						    priv->sasl_had_clientout ? NULL : &initial_clientout,
						    priv->sasl_had_clientout ? NULL : &initial_clientoutlen))
      {
	g_assert(priv->sasl_mechanism != NULL);

	if (initial_clientoutlen > 0)
	  {
	    char buf64[initial_clientoutlen * 2]; /* Base64 is 33% larger than the data it encodes */
	    unsigned int outlen;
	    int result;
	    char *str;

	    result = sasl_encode64(initial_clientout, initial_clientoutlen, buf64, sizeof(buf64), &outlen);
	    if (result != SASL_OK)
	      return mn_client_session_set_error(session, MN_CLIENT_SESSION_ERROR_OTHER, _("unable to encode Base64: %s"), sasl_errstring(result, NULL, NULL));

	    str = g_strndup(buf64, outlen);
	    result = mn_client_session_write(session, "AUTH %s %s", priv->sasl_mechanism, str);
	    g_free(str);

	    priv->sasl_had_clientout = TRUE;
	    return result;
	  }
	else
	  {
	    priv->sasl_had_clientout = FALSE;
	    return mn_client_session_write(session, "AUTH %s", priv->sasl_mechanism);
	  }
      }
    else
      return priv->auth_mailbox->auth_cancelled
	? STATE_QUIT
	: self_session_authenticate_fallback(priv, FALSE, FALSE);
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SASL */
  }}
#line 777 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 473 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_auth_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 784 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_auth_cb"
{
#line 477 "src/mn-pop3-mailbox.gob"
	
#if WITH_SASL
    switch (response->type)
      {
      case RESPONSE_OK:
	return mn_client_session_sasl_authentication_done(session)
	  ? self_session_authenticated(priv)
	  : MN_CLIENT_SESSION_RESULT_DISCONNECT;

      case RESPONSE_ERR:
	if (priv->auth_mailbox->auth_cancelled)
	  return STATE_QUIT;
	else
	  {
	    if (priv->sasl_had_clientout)
	      {
		/*
		 * Some servers violate RFC 2449 by not supporting a
		 * second argument to the AUTH command. Support these
		 * servers nevertheless, by retrying without the SASL
		 * initial client response.
		 */

		mn_client_session_notice(session, _("SASL authentication with initial client response failed, retrying without initial client response"));
		return STATE_AUTH;
	      }
	    else
	      return self_session_authenticate_fallback(priv, FALSE, FALSE);
	  }

      case RESPONSE_CONTINUATION:
	return mn_client_session_sasl_authentication_step(session, response->arguments);

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
#else
    g_assert_not_reached();
    return 0;
#endif /* WITH_SASL */
  }}
#line 829 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 519 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_apop_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 836 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_apop_cb"
{
#line 522 "src/mn-pop3-mailbox.gob"
	
    MNMD5Context context;
    char buf[16];
    char hexbuf[33];

    g_assert(priv->apop_timestamp != NULL);

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

    mn_md5_init_ctx(&context);
    mn_md5_process_bytes(&context, priv->apop_timestamp, strlen(priv->apop_timestamp));
    mn_md5_process_bytes(&context, priv->auth_mailbox->runtime_password, strlen(priv->auth_mailbox->runtime_password));
    mn_md5_finish_ctx(&context, buf);
    mn_md5_to_hex(buf, hexbuf);

    return mn_client_session_write(session, "APOP %s %s", priv->auth_mailbox->username, hexbuf);
  }}
#line 858 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 541 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_apop_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 865 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_apop_cb"
#line 541 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (session != NULL, (int )0);
#line 541 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (response != NULL, (int )0);
#line 541 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 873 "mn-pop3-mailbox.c"
{
#line 545 "src/mn-pop3-mailbox.gob"
	
    switch (response->type)
      {
      case RESPONSE_OK:
	return self_session_authenticated(priv);

      case RESPONSE_ERR:
	return self_session_authenticate_fallback(priv, TRUE, FALSE);

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 889 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 559 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_user_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 896 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_user_cb"
#line 559 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (session != NULL, (int )0);
#line 559 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 902 "mn-pop3-mailbox.c"
{
#line 562 "src/mn-pop3-mailbox.gob"
	
    return mn_client_session_write(session, "USER %s", priv->auth_mailbox->username);
  }}
#line 908 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 566 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_user_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 915 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_user_cb"
{
#line 570 "src/mn-pop3-mailbox.gob"
	
    switch (response->type)
      {
      case RESPONSE_OK:
	return STATE_PASS;

      case RESPONSE_ERR:
	mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);
	return STATE_QUIT;

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 933 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 585 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_pass_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 940 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_pass_cb"
{
#line 588 "src/mn-pop3-mailbox.gob"
	
    if (! mn_authenticated_mailbox_fill_password(priv->auth_mailbox, TRUE))
      return STATE_QUIT;

    return mn_client_session_write(session, "PASS %s", priv->auth_mailbox->runtime_password);
  }}
#line 950 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 595 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_pass_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 957 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_pass_cb"
{
#line 599 "src/mn-pop3-mailbox.gob"
	
    switch (response->type)
      {
      case RESPONSE_OK:
	return self_session_authenticated(priv);

      case RESPONSE_ERR:
	return self_session_authenticate_fallback(priv, TRUE, TRUE);

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 974 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 613 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_list_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 981 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_list_cb"
{
#line 616 "src/mn-pop3-mailbox.gob"
	
    return mn_client_session_write(session, "LIST");
  }}
#line 988 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 620 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_list_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 995 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_list_cb"
{
#line 624 "src/mn-pop3-mailbox.gob"
	
    self_session_handle_list_response(priv, response, FALSE);

    switch (response->type)
      {
      case RESPONSE_OK:
	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      case RESPONSE_LIST_END:
	return self_session_enter_retr_top(priv);

      case RESPONSE_ERR:
	return mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);

      case RESPONSE_LIST_ITEM:
	{
	  int num;
	  int size;

	  if (sscanf(response->arguments, "%d %d", &num, &size) == 2)
	    priv->messages = g_slist_prepend(priv->messages, self_message_info_new(num));
	  else			/* compliance error */
	    return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	}
	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 1029 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 655 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_uidl_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1036 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_uidl_cb"
{
#line 658 "src/mn-pop3-mailbox.gob"
	
    return mn_client_session_write(session, "UIDL");
  }}
#line 1043 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 662 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_uidl_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1050 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_uidl_cb"
{
#line 666 "src/mn-pop3-mailbox.gob"
	
    self_session_handle_list_response(priv, response, FALSE);

    switch (response->type)
      {
      case RESPONSE_OK:
	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      case RESPONSE_LIST_END:
	return self_session_enter_retr_top(priv);

      case RESPONSE_ERR:
	/*
	 * The server advertised UIDL but does not support it,
	 * fallback to LIST.
	 */
	return STATE_LIST;

      case RESPONSE_LIST_ITEM:
	{
	  int num;
	  char *uid;

	  if (self_parse_uidl_list_item(response->arguments, &num, &uid))
	    {
	      MessageInfo *info;
	      MNMessage *message;

	      info = self_message_info_new(num);
	      info->mid = uid;

	      message = mn_mailbox_get_message_from_mid(priv->mailbox, info->mid);
	      if (message)
		info->message = g_object_ref(message);

	      priv->messages = g_slist_prepend(priv->messages, info);

	      return MN_CLIENT_SESSION_RESULT_CONTINUE;
	    }
	  else
	    /* compliance error */
	    return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
	}

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 1102 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 715 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_retr_top_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1109 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_retr_top_cb"
{
#line 718 "src/mn-pop3-mailbox.gob"
	
    MessageInfo *info;

    info = self_session_message_iter_get_message_info(priv);

    if (info)
      return mn_client_session_write(session, priv->top_supported ? "TOP %i 0" : "RETR %i", info->number);
    else
      {
	GSList *messages = NULL;
	GSList *l;

	MN_LIST_FOREACH(l, priv->messages)
	  {
	    info = l->data;

	    if (info->message)
	      messages = g_slist_prepend(messages, info->message);
	  }

	GDK_THREADS_ENTER();

	mn_mailbox_set_messages(priv->mailbox, messages);

	if (priv->num_errors != 0)
	  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
	 * unreffing the messages. We have just exposed the messages
	 * to other threads through our mn_mailbox_set_messages()
	 * call, so unref them here, while we hold the GDK lock.
	 */
	mn_g_slist_clear_deep_custom(&priv->messages, (GFunc) self_message_info_free, NULL);

	gdk_flush();
	GDK_THREADS_LEAVE();

	g_slist_free(messages);

	return STATE_QUIT;
      }
  }}
#line 1160 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 766 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_retr_top_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1167 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_retr_top_cb"
{
#line 770 "src/mn-pop3-mailbox.gob"
	
    self_session_handle_list_response(priv, response, TRUE);

    switch (response->type)
      {
      case RESPONSE_OK:
	if (priv->message_buffer)
	  g_string_free(priv->message_buffer, TRUE);
	priv->message_buffer = g_string_new(NULL);
	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      case RESPONSE_LIST_END:
	{
	  MessageInfo *info = priv->message_iter->data;
	  GError *err = NULL;

	  g_assert(info->message == NULL);

	  info->message = mn_message_new_from_buffer(priv->mailbox,
						     priv->message_buffer->str,
						     priv->message_buffer->len,
						     info->mid,
						     0,
						     TRUE,
						     &err);
	  if (err)
	    {
	      mn_client_session_warning(session,
					"cannot read message %i: %s",
					info->number,
					err->message);
	      g_error_free(err);

	      priv->num_errors++;
	    }

	  priv->message_iter = priv->message_iter->next;
	  return STATE_RETR_TOP;
	}

      case RESPONSE_ERR:
	{
	  MessageInfo *info = priv->message_iter->data;

	  g_assert(info->message == NULL);

	  mn_client_session_warning(session,
				    "cannot retrieve message %i: %s",
				    info->number,
				    response->arguments ? response->arguments : "unknown error");
	  priv->num_errors++;

	  priv->message_iter = priv->message_iter->next;
	  return STATE_RETR_TOP;
	}

      case RESPONSE_LIST_ITEM:
	g_string_append_printf(priv->message_buffer, "%s\n", response->arguments);
	return MN_CLIENT_SESSION_RESULT_CONTINUE;

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 1235 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 835 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_enter_quit_cb (MNClientSession * session, MNClientSessionPrivate * priv)
{
#line 1242 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::enter_quit_cb"
{
#line 838 "src/mn-pop3-mailbox.gob"
	
    return mn_client_session_write(session, "QUIT");
  }}
#line 1249 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 842 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_handle_quit_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1256 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::handle_quit_cb"
{
#line 846 "src/mn-pop3-mailbox.gob"
	
    switch (response->type)
      {
      case RESPONSE_OK:
	return MN_CLIENT_SESSION_RESULT_DISCONNECT;

      case RESPONSE_ERR:
	return mn_client_session_set_error_from_response(session, MN_CLIENT_SESSION_ERROR_OTHER, response->arguments);

      default:
	return MN_CLIENT_SESSION_RESULT_BAD_RESPONSE_FOR_CONTEXT;
      }
  }}
#line 1273 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 860 "src/mn-pop3-mailbox.gob"
static void 
___1a_mn_pop3_mailbox_authenticated_check (MNAuthenticatedMailbox * mailbox G_GNUC_UNUSED)
#line 1279 "mn-pop3-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:POP3:Mailbox::authenticated_check"
{
#line 862 "src/mn-pop3-mailbox.gob"
	
    Self *self = SELF(mailbox);
    static const MNClientSessionState states[] = {
      { STATE_GREETING,		NULL,			self_handle_greeting_cb },
      { STATE_CAPA,		self_enter_capa_cb,	self_handle_capa_cb },
#if WITH_SSL
      { STATE_STLS,		self_enter_stls_cb,	self_handle_stls_cb },
#endif
#if WITH_SASL
      { STATE_AUTH,		self_enter_auth_cb,	self_handle_auth_cb },
#endif
      { STATE_APOP,		self_enter_apop_cb,	self_handle_apop_cb },
      { STATE_USER,		self_enter_user_cb,	self_handle_user_cb },
      { STATE_PASS,		self_enter_pass_cb,	self_handle_pass_cb },
      { STATE_LIST,		self_enter_list_cb,	self_handle_list_cb },
      { STATE_UIDL,		self_enter_uidl_cb,	self_handle_uidl_cb },
      { STATE_RETR_TOP,		self_enter_retr_top_cb,	self_handle_retr_top_cb },
      { STATE_QUIT,		self_enter_quit_cb,	self_handle_quit_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,
      NULL,			/* pre_read */
      NULL,			/* post_read */
#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;

    if (selfp->login_delay && selfp->authentication_timer)
      {
	double elapsed;

	g_timer_stop(selfp->authentication_timer);
	elapsed = g_timer_elapsed(selfp->authentication_timer, NULL);

	if (elapsed < selfp->login_delay)
	  {
	    int sleeptime;

	    sleeptime = selfp->login_delay - elapsed;
	    mn_mailbox_notice(MN_MAILBOX(self),
			      ngettext("honouring LOGIN-DELAY, sleeping for %i second",
				       "honouring LOGIN-DELAY, sleeping for %i seconds",
				       sleeptime),
			      sleeptime);
	    sleep(sleeptime);
	  }
      }

    memset(&priv, 0, sizeof(priv));
    mn_pi_mailbox_session_private_init(MN_PI_MAILBOX(self), &priv);
    priv.self = self;

    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);

    if (! status)
      {
	char *escaped;

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

	GDK_THREADS_ENTER();

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

	gdk_flush();
	GDK_THREADS_LEAVE();

	g_free(escaped);
      }

    g_free(priv.apop_timestamp);
    mn_g_slist_free_deep(priv.auth_mechanisms);

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

    mn_g_slist_free_deep_custom(priv.messages, (GFunc) self_message_info_free, NULL);

    if (priv.message_buffer)
      g_string_free(priv.message_buffer, TRUE);
  }}
#line 1396 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__
#undef PARENT_HANDLER

#line 972 "src/mn-pop3-mailbox.gob"
static MNClientSessionResponse * 
mn_pop3_mailbox_response_new_cb (MNClientSession * session, const char * input, MNClientSessionPrivate * priv)
{
#line 1404 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::response_new_cb"
{
#line 976 "src/mn-pop3-mailbox.gob"
	
    MNClientSessionResponse *response = NULL;

    /*
     * About character set handling:
     *
     * RFC 1939 3 specifies that "keywords and arguments consist of
     * printable ASCII characters", however that refers to
     * commands. Nothing is said about responses. We therefore do not
     * check the encoding of responses.
     *
     * 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
     *   - RETR/TOP multiline responses are passed to our
     *     mn-message-mime implementation, which handles character set
     *     conversions
     */

    if (priv->in_list)
      {
	response = g_new0(MNClientSessionResponse, 1);
	if (! strcmp(input, "."))
	  response->type = RESPONSE_LIST_END;
	else if (g_str_has_prefix(input, ".."))
	  {
	    response->type = RESPONSE_LIST_ITEM;
	    response->arguments = g_strdup(input + 1); /* skip the initial dot */
	  }
	else
	  {
	    response->type = RESPONSE_LIST_ITEM;
	    response->arguments = g_strdup(input);
	  }
      }
    else
      {
	if (g_str_has_prefix(input, "+ "))
	  {
	    response = g_new0(MNClientSessionResponse, 1);
	    response->type = RESPONSE_CONTINUATION;
	    response->arguments = g_strdup(input + 2);
	  }
	else
	  {
	    ResponseType type;
	    int after_status = 0;

	    if (g_str_has_prefix(input, "+OK"))
	      {
		type = RESPONSE_OK;
		after_status = 3;
	      }
	    else if (g_str_has_prefix(input, "-ERR"))
	      {
		type = RESPONSE_ERR;
		after_status = 4;
	      }

	    if (after_status)
	      {
		char c = input[after_status];

		if (c == ' ' || c == ',') /* skip commonly used separators */
		  after_status++;

		response = g_new0(MNClientSessionResponse, 1);
		response->type = type;
		if (input[after_status] != 0)
		  response->arguments = g_strdup(input + after_status);
	      }
	  }
      }

    return response;
  }}
#line 1487 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1056 "src/mn-pop3-mailbox.gob"
static void 
mn_pop3_mailbox_response_free_cb (MNClientSession * session, MNClientSessionResponse * response, MNClientSessionPrivate * priv)
{
#line 1494 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::response_free_cb"
{
#line 1060 "src/mn-pop3-mailbox.gob"
	
    g_free(response->arguments);
    g_free(response);
  }}
#line 1502 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1065 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_session_authenticate (MNClientSessionPrivate * priv)
{
#line 1509 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_authenticate"
#line 1065 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 1513 "mn-pop3-mailbox.c"
{
#line 1067 "src/mn-pop3-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_AUTH;
#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_QUIT;
#endif /* WITH_SASL */
	  }
	else
	  {
	    if (! strcmp(priv->pi_mailbox->authmech, "+APOP"))
	      {
		if (priv->apop_timestamp)
		  return STATE_APOP;
		else
		  {
		    mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("server does not support APOP authentication"));
		    return STATE_QUIT;
		  }
	      }
	    else if (! strcmp(priv->pi_mailbox->authmech, "+USERPASS"))
	      return STATE_USER;
	    else
	      {
		mn_client_session_set_error(priv->session, MN_CLIENT_SESSION_ERROR_OTHER, _("unknown authentication mechanism \"%s\""), priv->pi_mailbox->authmech);
		return STATE_QUIT;
	      }
	  }
      }
    else
      {
#if WITH_SASL
	if (priv->sasl_remaining_mechanisms)
	  return STATE_AUTH;
#endif /* WITH_SASL */
	if (priv->apop_timestamp)
	  return STATE_APOP;
	else
	  return STATE_USER;
      }
  }}
#line 1566 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1118 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_session_authenticate_fallback (MNClientSessionPrivate * priv, gboolean tried_apop, gboolean tried_pass)
{
#line 1573 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_authenticate_fallback"
#line 1118 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 1577 "mn-pop3-mailbox.c"
{
#line 1122 "src/mn-pop3-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_AUTH;
		  }
	      }
	  }

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

	if (! tried_apop && priv->apop_timestamp)
	  {
	    mn_client_session_notice(priv->session, _("falling back to APOP authentication"));
	    return STATE_APOP;
	  }
	else if (! tried_pass)
	  {
	    mn_client_session_notice(priv->session, _("falling back to USER/PASS authentication"));
	    return STATE_USER;
	  }
      }

    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_QUIT;
      }
  }}
#line 1627 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1170 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_session_authenticated (MNClientSessionPrivate * priv)
{
#line 1634 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_authenticated"
#line 1170 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 1638 "mn-pop3-mailbox.c"
{
#line 1172 "src/mn-pop3-mailbox.gob"
	
    priv->authenticated = TRUE;
    if (priv->self->_priv->login_delay)
      {
	if (priv->self->_priv->authentication_timer)
	  g_timer_start(priv->self->_priv->authentication_timer);
	else
	  priv->self->_priv->authentication_timer = g_timer_new();
      }

    /*
     * We are now in transaction state. We must re-issue CAPA if:
     *
     *   - the LOGIN-DELAY capability announced in the authorization
     *     state contained the USER argument (priv->login_delay_user is
     *     true)
     *   - the TOP capability was not announced in the authorization
     *     state: although RFC 2449 states that "capabilities available
     *     in the AUTHORIZATION state MUST be announced in both states",
     *     some servers (for instance, pop.gmail.com) violate the RFC
     *     and only announce TOP in the transaction state.
     */
    return priv->login_delay_user || ! priv->top_supported
      ? STATE_CAPA
      : self_session_enter_list_or_uidl(priv);
  }}
#line 1667 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1199 "src/mn-pop3-mailbox.gob"
static void 
mn_pop3_mailbox_session_handle_list_response (MNClientSessionPrivate * priv, MNClientSessionResponse * response, gboolean in_retr_top)
{
#line 1674 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_handle_list_response"
#line 1199 "src/mn-pop3-mailbox.gob"
	g_return_if_fail (priv != NULL);
#line 1199 "src/mn-pop3-mailbox.gob"
	g_return_if_fail (response != NULL);
#line 1680 "mn-pop3-mailbox.c"
{
#line 1203 "src/mn-pop3-mailbox.gob"
	
    switch (response->type)
      {
      case RESPONSE_OK:
	priv->in_list = TRUE;
	priv->in_retr_top = in_retr_top;
	break;

      case RESPONSE_LIST_ITEM:	/* nop */
	break;

      default:
	priv->in_list = FALSE;
	priv->in_retr_top = FALSE;
	break;
      }
  }}
#line 1700 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1221 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_session_enter_list_or_uidl (MNClientSessionPrivate * priv)
{
#line 1707 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_enter_list_or_uidl"
#line 1221 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 1711 "mn-pop3-mailbox.c"
{
#line 1223 "src/mn-pop3-mailbox.gob"
	
    if (priv->uidl_supported)
      return STATE_UIDL;
    else
      return STATE_LIST;
  }}
#line 1720 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1230 "src/mn-pop3-mailbox.gob"
static int 
mn_pop3_mailbox_session_enter_retr_top (MNClientSessionPrivate * priv)
{
#line 1727 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_enter_retr_top"
#line 1230 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (int )0);
#line 1731 "mn-pop3-mailbox.c"
{
#line 1232 "src/mn-pop3-mailbox.gob"
	
    priv->message_iter = priv->messages;

    return STATE_RETR_TOP;
  }}
#line 1739 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1238 "src/mn-pop3-mailbox.gob"
static MessageInfo * 
mn_pop3_mailbox_session_message_iter_get_message_info (MNClientSessionPrivate * priv)
{
#line 1746 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::session_message_iter_get_message_info"
#line 1238 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (priv != NULL, (MessageInfo * )0);
#line 1750 "mn-pop3-mailbox.c"
{
#line 1240 "src/mn-pop3-mailbox.gob"
	
    for (; priv->message_iter; priv->message_iter = priv->message_iter->next)
      {
	MessageInfo *info = priv->message_iter->data;

	if (! info->message)
	  return info;
      }

    return NULL;
  }}
#line 1764 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1252 "src/mn-pop3-mailbox.gob"
static gboolean 
mn_pop3_mailbox_parse_uidl_list_item (const char * item, int * number, char ** uid)
{
#line 1771 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::parse_uidl_list_item"
#line 1252 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (item != NULL, (gboolean )0);
#line 1252 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (number != NULL, (gboolean )0);
#line 1252 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (uid != NULL, (gboolean )0);
#line 1779 "mn-pop3-mailbox.c"
{
#line 1256 "src/mn-pop3-mailbox.gob"
	
    char **fields;
    gboolean status = FALSE;

    fields = g_strsplit(item, " ", 2);
    if (g_strv_length(fields) == 2 && mn_str_isnumeric(fields[0]))
      {
	*number = atoi(fields[0]);
	*uid = g_strdup(fields[1]);
	status = TRUE;
      }
    g_strfreev(fields);

    return status;
  }}
#line 1797 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1272 "src/mn-pop3-mailbox.gob"
static MessageInfo * 
mn_pop3_mailbox_message_info_new (int number)
{
#line 1804 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::message_info_new"
{
#line 1274 "src/mn-pop3-mailbox.gob"
	
    MessageInfo *info;

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

    return info;
  }}
#line 1816 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1283 "src/mn-pop3-mailbox.gob"
static void 
mn_pop3_mailbox_message_info_free (MessageInfo * info)
{
#line 1823 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::message_info_free"
#line 1283 "src/mn-pop3-mailbox.gob"
	g_return_if_fail (info != NULL);
#line 1827 "mn-pop3-mailbox.c"
{
#line 1285 "src/mn-pop3-mailbox.gob"
	
    if (info->message)
      g_object_unref(info->message);
    g_free(info->mid);
    g_free(info);
  }}
#line 1836 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__

#line 1292 "src/mn-pop3-mailbox.gob"
char * 
mn_pop3_mailbox_build_name (const char * username, const char * server)
{
#line 1843 "mn-pop3-mailbox.c"
#define __GOB_FUNCTION__ "MN:POP3:Mailbox::build_name"
#line 1292 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (username != NULL, (char * )0);
#line 1292 "src/mn-pop3-mailbox.gob"
	g_return_val_if_fail (server != NULL, (char * )0);
#line 1849 "mn-pop3-mailbox.c"
{
#line 1295 "src/mn-pop3-mailbox.gob"
	
    return g_strdup_printf("%s@%s", username, server);
  }}
#line 1855 "mn-pop3-mailbox.c"
#undef __GOB_FUNCTION__
