Renamed from session.c and made to be a subclass of CamelSession.

* mail-session.c: Renamed from session.c and made to be a subclass
	of CamelSession.

	* mail-mt.c (mail_user_message): Renamed from mail_get_accept and
	made more general-purpose, to implement the new
	camel_session_alert_user.

svn path=/trunk/; revision=9618
This commit is contained in:
Dan Winship
2001-04-27 21:08:51 +00:00
parent 63e96e1002
commit d4b3c14fcd
5 changed files with 261 additions and 233 deletions

View File

@ -1,3 +1,12 @@
2001-04-27 Dan Winship <danw@ximian.com>
* mail-session.c: Renamed from session.c and made to be a subclass
of CamelSession.
* mail-mt.c (mail_user_message): Renamed from mail_get_accept and
made more general-purpose, to implement the new
camel_session_alert_user.
2001-04-26 Jeffrey Stedfast <fejj@ximian.com>
* main.c (main): No need to camel_shutdown() anymore...

View File

@ -86,6 +86,8 @@ evolution_mail_SOURCES = \
mail-search-dialogue.h \
mail-send-recv.c \
mail-send-recv.h \
mail-session.c \
mail-session.h \
mail-summary.c \
mail-summary.h \
mail-tools.c \
@ -98,8 +100,6 @@ evolution_mail_SOURCES = \
main.c \
message-list.c \
message-list.h \
session.c \
mail-session.h \
subscribe-dialog.c \
subscribe-dialog.h \
mail.h

View File

@ -664,69 +664,57 @@ mail_get_password(const char *prompt, gboolean secret)
/* ********************************************************************** */
struct _accept_msg {
struct _user_message_msg {
struct _mail_msg msg;
const char *type;
const char *prompt;
gboolean allow_cancel;
gboolean result;
};
static void
do_get_accept (struct _mail_msg *mm)
do_user_message (struct _mail_msg *mm)
{
struct _accept_msg *m = (struct _accept_msg *)mm;
struct _user_message_msg *m = (struct _user_message_msg *)mm;
GtkWidget *dialog;
GtkWidget *label;
dialog = gnome_dialog_new (_("Do you accept?"),
GNOME_STOCK_BUTTON_YES,
GNOME_STOCK_BUTTON_NO,
NULL);
dialog = gnome_message_box_new (m->prompt, m->type,
m->allow_cancel ? GNOME_STOCK_BUTTON_CANCEL : GNOME_STOCK_BUTTON_OK,
m->allow_cancel ? GNOME_STOCK_BUTTON_OK: NULL,
NULL);
gnome_dialog_set_default (GNOME_DIALOG (dialog), 1);
gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, TRUE, TRUE);
label = gtk_label_new (m->prompt);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label,
TRUE, TRUE, 0);
gtk_widget_show (label);
/* hrm, we can't run this async since the gui_port from which we're called
will reply to our message for us */
m->result = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0;
m->result = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) != 0;
}
static void
do_free_accept (struct _mail_msg *mm)
{
/*struct _accept_msg *m = (struct _accept_msg *)mm;*/
/* nothing to do here */
}
struct _mail_msg_op get_accept_op = {
struct _mail_msg_op user_message_op = {
NULL,
do_user_message,
NULL,
do_get_accept,
NULL,
do_free_accept,
};
/* prompt the user with a yes/no question and return the response */
gboolean
mail_get_accept (const char *prompt)
mail_user_message (const char *type, const char *prompt, gboolean allow_cancel)
{
struct _accept_msg *m, *r;
EMsgPort *accept_reply;
struct _user_message_msg *m, *r;
EMsgPort *user_message_reply;
gboolean accept;
accept_reply = e_msgport_new ();
user_message_reply = e_msgport_new ();
m = mail_msg_new (&get_accept_op, accept_reply, sizeof (*m));
m = mail_msg_new (&user_message_op, user_message_reply, sizeof (*m));
m->type = type;
m->prompt = prompt;
m->allow_cancel = allow_cancel;
if (pthread_self () == mail_gui_thread) {
do_get_accept ((struct _mail_msg *)m);
do_user_message ((struct _mail_msg *)m);
r = m;
} else {
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
@ -734,8 +722,8 @@ mail_get_accept (const char *prompt)
/* we want this single-threaded, this is the easiest way to do it without blocking ? */
pthread_mutex_lock (&lock);
e_msgport_put (mail_gui_port, (EMsg *)m);
e_msgport_wait (accept_reply);
r = (struct _accept_msg *)e_msgport_get (accept_reply);
e_msgport_wait (user_message_reply);
r = (struct _user_message_msg *)e_msgport_get (user_message_reply);
pthread_mutex_unlock (&lock);
}
@ -744,7 +732,7 @@ mail_get_accept (const char *prompt)
accept = m->result;
mail_msg_free (m);
e_msgport_destroy (accept_reply);
e_msgport_destroy (user_message_reply);
return accept;
}

View File

@ -68,8 +68,10 @@ void mail_status(const char *msg);
/* request a string/password */
char *mail_get_password (const char *prompt, gboolean secret);
/* request a yes/no response as to whether or not to accept (a certificate?) */
gboolean mail_get_accept (const char *prompt);
/* present information and get an ok (or possibly cancel)
* "type" is as for gnome_message_box_new();
*/
gboolean mail_user_message (const char *type, const char *prompt, gboolean allow_cancel);
/* forward a camel event (or other call) to the gui thread */
int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data);

View File

@ -1,8 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* mail-session.c: handles the session information and resource manipulation */
/*
* Authors: Miguel de Icaza <miguel@gnu.org>
*
* Copyright 2001 Ximian, Inc. (www.ximian.com)
*
* This program is free software; you can redistribute it and/or modify
@ -30,6 +28,7 @@
#include <libgnome/gnome-config.h>
#include <libgnomeui/gnome-dialog.h>
#include <libgnomeui/gnome-dialog-util.h>
#include <libgnomeui/gnome-messagebox.h>
#include <libgnomeui/gnome-stock.h>
#include "mail.h"
#include "mail-session.h"
@ -37,211 +36,175 @@
CamelSession *session;
static GHashTable *passwords;
static gboolean interaction_enabled;
#define MAIL_SESSION_TYPE (mail_session_get_type ())
#define MAIL_SESSION(obj) (CAMEL_CHECK_CAST((obj), MAIL_SESSION_TYPE, MailSession))
#define MAIL_SESSION_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), MAIL_SESSION_TYPE, MailSessionClass))
#define MAIL_IS_SESSION(o) (CAMEL_CHECK_TYPE((o), MAIL_SESSION_TYPE))
typedef struct _MailSession {
CamelSession parent_object;
GHashTable *passwords;
gboolean interaction_enabled;
} MailSession;
typedef struct _MailSessionClass {
CamelSessionClass parent_class;
} MailSessionClass;
static char *get_password (CamelSession *session, const char *prompt,
gboolean secret, CamelService *service,
const char *item, CamelException *ex);
static void forget_password (CamelSession *session, CamelService *service,
const char *item, CamelException *ex);
static gboolean alert_user (CamelSession *session, CamelSessionAlertType type,
const char *prompt, gboolean cancel);
static guint register_timeout (CamelSession *session, guint32 interval,
CamelTimeoutCallback cb, gpointer camel_data);
static gboolean remove_timeout (CamelSession *session, guint handle);
static char *decode_base64 (char *base64);
static void
request_callback (gchar *string, gpointer data)
init (MailSession *session)
{
char **ans = data;
char *key, *value;
void *iter;
if (string)
*ans = string;
else
*ans = NULL;
}
session->passwords = g_hash_table_new (g_str_hash, g_str_equal);
char *
mail_session_request_dialog (const char *prompt, gboolean secret, const char *key,
gboolean async)
{
GtkWidget *dialog;
char *ans;
if (!passwords)
passwords = g_hash_table_new (g_str_hash, g_str_equal);
ans = g_hash_table_lookup (passwords, key);
if (ans)
return g_strdup (ans);
if (!interaction_enabled)
return NULL;
if (!async) {
dialog = gnome_request_dialog (secret, prompt, NULL, 0,
request_callback, &ans, NULL);
if (!dialog)
return NULL;
if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == -1 ||
ans == NULL)
return NULL;
} else {
if ((ans = mail_get_password (prompt, secret)) == NULL)
return NULL;
}
g_hash_table_insert (passwords, g_strdup (key), g_strdup (ans));
return ans;
}
gboolean
mail_session_accept_dialog (const char *prompt, const char *key, gboolean async)
{
GtkWidget *dialog;
GtkWidget *label;
if (!interaction_enabled)
return FALSE;
if (!async) {
dialog = gnome_dialog_new (_("Do you accept?"),
GNOME_STOCK_BUTTON_YES,
GNOME_STOCK_BUTTON_NO,
NULL);
gnome_dialog_set_default (GNOME_DIALOG (dialog), 1);
gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, TRUE, TRUE);
label = gtk_label_new (prompt);
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label,
TRUE, TRUE, 0);
gtk_widget_show (label);
if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0)
return TRUE;
else
return FALSE;
} else {
return mail_get_accept (prompt);
iter = gnome_config_private_init_iterator ("/Evolution/Passwords");
if (iter) {
while (gnome_config_iterator_next (iter, &key, &value)) {
g_hash_table_insert (session->passwords,
decode_base64 (key),
decode_base64 (value));
g_free (key);
g_free (value);
}
}
}
static gpointer
auth_callback (CamelAuthCallbackMode mode, char *data, gboolean secret,
CamelService *service, char *item, CamelException *ex)
static void
class_init (MailSessionClass *mail_session_class)
{
char *key, *ans, *url;
gboolean accept;
gpointer old_key, old_data;
CamelSessionClass *camel_session_class =
CAMEL_SESSION_CLASS (mail_session_class);
/* virtual method override */
camel_session_class->get_password = get_password;
camel_session_class->forget_password = forget_password;
camel_session_class->alert_user = alert_user;
camel_session_class->register_timeout = register_timeout;
camel_session_class->remove_timeout = remove_timeout;
}
CamelType
mail_session_get_type (void)
{
static CamelType mail_session_type = CAMEL_INVALID_TYPE;
if (mail_session_type == CAMEL_INVALID_TYPE) {
mail_session_type = camel_type_register (
camel_session_get_type (), "MailSession",
sizeof (MailSession),
sizeof (MailSessionClass),
(CamelObjectClassInitFunc) class_init,
NULL,
(CamelObjectInitFunc) init,
NULL);
}
return mail_session_type;
}
static char *
make_key (CamelService *service, const char *item)
{
char *key, *url;
if (service) {
url = camel_url_to_string (service->url, CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_PARAMS);
key = g_strdup_printf ("%s:%s", url, item);
g_free (url);
} else
key = g_strdup (item);
switch (mode) {
case CAMEL_AUTHENTICATOR_TELL:
if (g_hash_table_lookup_extended (passwords, key,
&old_key, &old_data)) {
g_free (old_data);
g_free (key);
key = old_key;
}
if (!data) {
g_hash_table_remove (passwords, key);
g_free (key);
} else {
g_hash_table_insert (passwords, key, data);
}
return NULL;
break;
case CAMEL_AUTHENTICATOR_ASK:
ans = mail_session_request_dialog (data, secret, key, TRUE);
g_free (key);
if (!ans) {
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
"User canceled operation.");
}
return ans;
break;
case CAMEL_AUTHENTICATOR_ACCEPT:
accept = mail_session_accept_dialog (data, key, TRUE);
g_free (key);
return GINT_TO_POINTER (accept);
break;
}
return NULL;
return key;
}
static char *
decode_base64 (char *base64)
get_password (CamelSession *session, const char *prompt, gboolean secret,
CamelService *service, const char *item, CamelException *ex)
{
char *plain, *pad = "==";
int len, out, state, save;
MailSession *mail_session = MAIL_SESSION (session);
char *key, *ans;
len = strlen (base64);
plain = g_malloc0 (len);
state = save = 0;
out = base64_decode_step (base64, len, plain, &state, &save);
if (len % 4) {
base64_decode_step (pad, 4 - len % 4, plain + out,
&state, &save);
key = make_key (service, item);
ans = g_hash_table_lookup (mail_session->passwords, key);
if (ans) {
g_free (key);
return g_strdup (ans);
}
return plain;
if (!mail_session->interaction_enabled ||
!(ans = mail_get_password (prompt, secret))) {
g_free (key);
camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
_("User canceled operation."));
return NULL;
}
g_hash_table_insert (mail_session->passwords, key, g_strdup (ans));
return ans;
}
static void
maybe_remember_password (gpointer key, gpointer password, gpointer url)
forget_password (CamelSession *session, CamelService *service,
const char *item, CamelException *ex)
{
char *path, *key64, *pass64;
int len, state, save;
MailSession *mail_session = MAIL_SESSION (session);
char *key = make_key (service, item);
gpointer old_key, old_data;
len = strlen (url);
if (strncmp (key, url, len) != 0)
if (!g_hash_table_lookup_extended (mail_session->passwords, key,
&old_key, &old_data))
return;
len = strlen (key);
key64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
state = save = 0;
base64_encode_close (key, len, FALSE, key64, &state, &save);
path = g_strdup_printf ("/Evolution/Passwords/%s", key64);
g_free (key64);
len = strlen (password);
pass64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
state = save = 0;
base64_encode_close (password, len, FALSE, pass64, &state, &save);
gnome_config_private_set_string (path, pass64);
g_free (path);
g_free (pass64);
g_hash_table_remove (mail_session->passwords, key);
g_free (old_data);
g_free (old_key);
}
void
mail_session_remember_password (const char *url_string)
static gboolean
alert_user (CamelSession *session, CamelSessionAlertType type,
const char *prompt, gboolean cancel)
{
CamelURL *url;
char *simple_url;
MailSession *mail_session = MAIL_SESSION (session);
const char *message_type;
url = camel_url_new (url_string, NULL);
simple_url = camel_url_to_string (url, CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_PARAMS);
camel_url_free (url);
if (!mail_session->interaction_enabled)
return FALSE;
g_hash_table_foreach (passwords, maybe_remember_password, simple_url);
g_free (simple_url);
}
void
mail_session_forget_password (const char *key)
{
gpointer okey, value;
if (g_hash_table_lookup_extended (passwords, key, &okey, &value)) {
g_hash_table_remove (passwords, key);
g_free (okey);
g_free (value);
switch (type) {
case CAMEL_SESSION_ALERT_INFO:
message_type = GNOME_MESSAGE_BOX_INFO;
break;
case CAMEL_SESSION_ALERT_WARNING:
message_type = GNOME_MESSAGE_BOX_WARNING;
break;
case CAMEL_SESSION_ALERT_ERROR:
message_type = GNOME_MESSAGE_BOX_ERROR;
break;
}
return mail_user_message (message_type, prompt, cancel);
}
/* ******************** */
@ -291,7 +254,7 @@ camel_timeout (gpointer data)
}
static guint
register_callback (guint32 interval, CamelTimeoutCallback cb, gpointer camel_data)
register_timeout (CamelSession *session, guint32 interval, CamelTimeoutCallback cb, gpointer camel_data)
{
struct _timeout_data *td;
@ -311,44 +274,105 @@ register_callback (guint32 interval, CamelTimeoutCallback cb, gpointer camel_dat
}
static gboolean
remove_callback (guint handle)
remove_timeout (CamelSession *session, guint handle)
{
gtk_timeout_remove (handle);
return TRUE;
}
/* ******************** */
static char *
decode_base64 (char *base64)
{
char *plain, *pad = "==";
int len, out, state, save;
len = strlen (base64);
plain = g_malloc0 (len);
state = save = 0;
out = base64_decode_step (base64, len, plain, &state, &save);
if (len % 4) {
base64_decode_step (pad, 4 - len % 4, plain + out,
&state, &save);
}
return plain;
}
static void
maybe_remember_password (gpointer key, gpointer password, gpointer url)
{
char *path, *key64, *pass64;
int len, state, save;
len = strlen (url);
if (strncmp (key, url, len) != 0)
return;
len = strlen (key);
key64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
state = save = 0;
base64_encode_close (key, len, FALSE, key64, &state, &save);
path = g_strdup_printf ("/Evolution/Passwords/%s", key64);
g_free (key64);
len = strlen (password);
pass64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
state = save = 0;
base64_encode_close (password, len, FALSE, pass64, &state, &save);
gnome_config_private_set_string (path, pass64);
g_free (path);
g_free (pass64);
}
void
mail_session_remember_password (const char *url_string)
{
GHashTable *passwords = MAIL_SESSION (session)->passwords;
CamelURL *url;
char *simple_url;
url = camel_url_new (url_string, NULL);
simple_url = camel_url_to_string (url, CAMEL_URL_HIDE_PASSWORD | CAMEL_URL_HIDE_PARAMS);
camel_url_free (url);
g_hash_table_foreach (passwords, maybe_remember_password, simple_url);
g_free (simple_url);
}
void
mail_session_forget_password (const char *key)
{
GHashTable *passwords = MAIL_SESSION (session)->passwords;
gpointer okey, value;
if (g_hash_table_lookup_extended (passwords, key, &okey, &value)) {
g_hash_table_remove (passwords, key);
g_free (okey);
g_free (value);
}
}
void
mail_session_init (void)
{
char *camel_dir, *key, *value;
void *iter;
char *camel_dir;
if (camel_init (evolution_dir, TRUE) != 0)
exit (0);
camel_dir = g_strdup_printf ("%s/mail", evolution_dir);
session = camel_session_new (camel_dir, auth_callback,
register_callback, remove_callback);
g_free (camel_dir);
passwords = g_hash_table_new (g_str_hash, g_str_equal);
iter = gnome_config_private_init_iterator ("/Evolution/Passwords");
if (iter) {
while (gnome_config_iterator_next (iter, &key, &value)) {
g_hash_table_insert (passwords, decode_base64 (key),
decode_base64 (value));
g_free (key);
g_free (value);
}
}
session = CAMEL_SESSION (camel_object_new (MAIL_SESSION_TYPE));
camel_dir = g_strdup_printf ("%s/mail", evolution_dir);
camel_session_construct (session, camel_dir);
g_free (camel_dir);
}
void
mail_session_enable_interaction (gboolean enable)
{
interaction_enabled = enable;
MAIL_SESSION (session)->interaction_enabled = enable;
}
static gboolean
@ -364,6 +388,8 @@ void
mail_session_forget_passwords (BonoboUIComponent *uih, void *user_data,
const char *path)
{
GHashTable *passwords = MAIL_SESSION (session)->passwords;
g_hash_table_foreach_remove (passwords, free_entry, NULL);
gnome_config_private_clean_section ("/Evolution/Passwords");
gnome_config_sync ();
@ -372,5 +398,8 @@ mail_session_forget_passwords (BonoboUIComponent *uih, void *user_data,
void
mail_session_set_password (const char *url, const char *password)
{
GHashTable *passwords = MAIL_SESSION (session)->passwords;
g_hash_table_insert (passwords, g_strdup (url), g_strdup (password));
}