balsa r7916 - in trunk: . libbalsa src
- From: pawels svn gnome org
- To: svn-commits-list gnome org
- Subject: balsa r7916 - in trunk: . libbalsa src
- Date: Fri, 25 Apr 2008 19:19:31 +0100 (BST)
Author: pawels
Date: Fri Apr 25 18:19:30 2008
New Revision: 7916
URL: http://svn.gnome.org/viewvc/balsa?rev=7916&view=rev
Log:
* src/balsa-mime-widget-message.c: use URIs instead of paths.
* src/sendmsg-window.[ch]: use gnome-vfs for attachment reading.
* src/balsa-mime-widget-callbacks.c: ditto.
* src/balsa-message.c: allow saving to URIs.
* src/main.c: -o flag accepts an URI now.
* src/information-dialog.h: add argument checking.
* libbalsa/misc.[hc]: return more detailed error information.
* libbalsa/body.h: store attachment URIs.
* libbalsa/send.[ch]: handle errors when reading from URIs.
* libbalsa/files.[ch]: file access operations use URIs now.
* libbalsa/misc.c: move some functions to libbalsa-vfs.c
* libbalsa/body.c: part operations accept URIs now.
Added:
trunk/libbalsa/libbalsa-vfs.c
trunk/libbalsa/libbalsa-vfs.h
Modified:
trunk/ChangeLog
trunk/libbalsa/Makefile.am
trunk/libbalsa/body.c
trunk/libbalsa/body.h
trunk/libbalsa/files.c
trunk/libbalsa/files.h
trunk/libbalsa/message.h
trunk/libbalsa/misc.c
trunk/libbalsa/misc.h
trunk/libbalsa/send.c
trunk/libbalsa/send.h
trunk/src/balsa-message.c
trunk/src/balsa-mime-widget-callbacks.c
trunk/src/balsa-mime-widget-message.c
trunk/src/information-dialog.h
trunk/src/main.c
trunk/src/sendmsg-window.c
trunk/src/sendmsg-window.h
Modified: trunk/libbalsa/Makefile.am
==============================================================================
--- trunk/libbalsa/Makefile.am (original)
+++ trunk/libbalsa/Makefile.am Fri Apr 25 18:19:30 2008
@@ -74,6 +74,8 @@
filter.h \
folder-scanners.c \
folder-scanners.h \
+ gmime-stream-gnome-vfs.c\
+ gmime-stream-gnome-vfs.h\
html.c \
html.h \
identity.c \
@@ -89,6 +91,8 @@
libbalsa.c \
libbalsa.h \
libbalsa_private.h \
+ libbalsa-vfs.c \
+ libbalsa-vfs.h \
mailbackend.h \
mailbox-filter.c \
mailbox-filter.h \
Modified: trunk/libbalsa/body.c
==============================================================================
--- trunk/libbalsa/body.c (original)
+++ trunk/libbalsa/body.c Fri Apr 25 18:19:30 2008
@@ -30,6 +30,7 @@
#include <fcntl.h>
#include "libbalsa.h"
+#include "libbalsa-vfs.h"
#include "misc.h"
#include <glib/gi18n.h>
@@ -45,6 +46,7 @@
body->embhdrs = NULL;
body->content_type = NULL;
body->filename = NULL;
+ body->file_uri = NULL;
body->temp_filename = NULL;
body->charset = NULL;
@@ -72,7 +74,8 @@
libbalsa_message_headers_destroy(body->embhdrs);
g_free(body->content_type);
g_free(body->filename);
-
+ if (body->file_uri)
+ g_object_unref(body->file_uri);
if (body->temp_filename)
unlink(body->temp_filename);
g_free(body->temp_filename);
@@ -322,8 +325,18 @@
body->temp_filename = tmp_file_name;
fd = open(body->temp_filename, O_WRONLY | O_EXCL | O_CREAT,
LIBBALSA_MESSAGE_BODY_SAFE);
- if (fd >= 0)
- return libbalsa_message_body_save_fd(body, fd, FALSE, err);
+ if (fd >= 0) {
+ GMimeStream *tmp_stream;
+
+ if ((tmp_stream = g_mime_stream_fs_new(fd)) != NULL)
+ return libbalsa_message_body_save_stream(body, tmp_stream, FALSE, err);
+ else {
+ g_set_error(err, LIBBALSA_ERROR_QUARK, 1,
+ _("Failed to create output stream"));
+ close(fd);
+ return FALSE;
+ }
+ }
} while (errno == EEXIST && --count > 0);
/* Either we hit a real error, or we used up 100 attempts. */
@@ -356,16 +369,42 @@
{
int fd;
int flags = O_CREAT | O_EXCL | O_WRONLY;
+ GMimeStream *out_stream;
#ifdef O_NOFOLLOW
flags |= O_NOFOLLOW;
#endif
- if ((fd=libbalsa_safe_open(filename, flags, mode)) < 0)
+ if ((fd = libbalsa_safe_open(filename, flags, mode, err)) < 0)
return FALSE;
- return libbalsa_message_body_save_fd(body, fd, filter_crlf, err);
+
+ if ((out_stream = g_mime_stream_fs_new(fd)) != NULL)
+ return libbalsa_message_body_save_stream(body, out_stream,
+ filter_crlf, err);
+
+ /* could not create stream */
+ g_set_error(err, LIBBALSA_ERROR_QUARK, 1,
+ _("Failed to create output stream"));
+ close(fd);
+ return FALSE;
+}
+
+
+gboolean
+libbalsa_message_body_save_vfs(LibBalsaMessageBody * body,
+ LibbalsaVfs * dest, mode_t mode,
+ gboolean filter_crlf,
+ GError **err)
+{
+ GMimeStream * out_stream;
+
+ if (!(out_stream = libbalsa_vfs_create_stream(dest, mode, TRUE, err)))
+ return FALSE;
+
+ return libbalsa_message_body_save_stream(body, out_stream, filter_crlf, err);
}
+
static GMimeStream *
libbalsa_message_body_stream_add_filter(GMimeStream * stream,
GMimeFilter * filter)
@@ -568,17 +607,17 @@
}
gboolean
-libbalsa_message_body_save_fd(LibBalsaMessageBody * body, int fd,
- gboolean filter_crlf, GError ** err)
+libbalsa_message_body_save_stream(LibBalsaMessageBody * body,
+ GMimeStream * dest, gboolean filter_crlf,
+ GError ** err)
{
- GMimeStream *stream, *stream_fs;
+ GMimeStream *stream;
ssize_t len;
stream = libbalsa_message_body_get_stream(body, err);
if (!body->mime_part)
return FALSE;
- stream_fs = g_mime_stream_fs_new(fd);
libbalsa_mailbox_lock_store(body->message->mailbox);
if (stream) {
@@ -600,7 +639,7 @@
g_object_unref(filter);
}
- len = g_mime_stream_write_to_stream(stream, stream_fs);
+ len = g_mime_stream_write_to_stream(stream, dest);
g_object_unref(stream);
} else {
/* body->mime_part is not a GMimePart. */
@@ -612,11 +651,11 @@
mime_part =
GMIME_OBJECT(GMIME_MESSAGE_PART(mime_part)->message);
- len = g_mime_object_write_to_stream(mime_part, stream_fs);
+ len = g_mime_object_write_to_stream(mime_part, dest);
}
libbalsa_mailbox_unlock_store(body->message->mailbox);
- g_object_unref(stream_fs);
+ g_object_unref(dest);
return len >= 0;
}
Modified: trunk/libbalsa/body.h
==============================================================================
--- trunk/libbalsa/body.h (original)
+++ trunk/libbalsa/body.h Fri Apr 25 18:19:30 2008
@@ -29,6 +29,7 @@
#include <gmime/gmime.h>
#include <gdk/gdk.h>
+#include "libbalsa-vfs.h"
#include "config.h"
#ifdef HAVE_GPGME
@@ -73,6 +74,7 @@
const gchar *content_dsp; /* content-disposition */
const gchar *content_id; /* content-id */
gchar *filename; /* holds filename for attachments and such (used mostly for sending) */
+ LibbalsaVfs * file_uri; /* file uri for attachments (used for sending) */
LibBalsaAttachMode attach_mode; /* attachment mode for sending */
gchar *temp_filename; /* Holds the filename of a the temporary file where this part is saved */
gchar *charset; /* the charset, used for sending, replying. */
@@ -103,11 +105,18 @@
GdkPixbuf *libbalsa_message_body_get_pixbuf(LibBalsaMessageBody * body,
GError ** err);
-gboolean libbalsa_message_body_save_fd(LibBalsaMessageBody * body, int fd,
- gboolean filter_crlf, GError **err);
+gboolean libbalsa_message_body_save_stream(LibBalsaMessageBody * body,
+ GMimeStream * dest,
+ gboolean filter_crlf,
+ GError **err);
gboolean libbalsa_message_body_save(LibBalsaMessageBody * body,
const gchar * filename, mode_t mode,
gboolean filter_crlf, GError **err);
+gboolean libbalsa_message_body_save_vfs(LibBalsaMessageBody * body,
+ LibbalsaVfs * dest,
+ mode_t mode,
+ gboolean filter_crlf,
+ GError **err);
gboolean libbalsa_message_body_save_temporary(LibBalsaMessageBody * body,
GError **err);
Modified: trunk/libbalsa/files.c
==============================================================================
--- trunk/libbalsa/files.c (original)
+++ trunk/libbalsa/files.c Fri Apr 25 18:19:30 2008
@@ -34,6 +34,7 @@
#include "misc.h"
#include "files.h"
#include <glib/gi18n.h>
+#include "libbalsa-vfs.h"
static const gchar *permanent_prefixes[] = {
/* BALSA_DATA_PREFIX,
@@ -132,7 +133,7 @@
* return the complete path to the icon file.
*/
GdkPixbuf *
-libbalsa_icon_finder(const char *mime_type, const char *filename,
+libbalsa_icon_finder(const char *mime_type, const LibbalsaVfs * for_file,
gchar** used_type, GtkIconSize size)
{
char *content_type;
@@ -142,6 +143,7 @@
#ifdef HAVE_GNOME
const char *icon_file;
GtkIconTheme *icon_theme;
+ const gchar * filename = NULL;
#endif
if (!gtk_icon_size_lookup(size, &width, &height))
@@ -149,9 +151,10 @@
if (mime_type)
content_type = g_strdup(mime_type);
- else if(filename)
- content_type = libbalsa_lookup_mime_type(filename);
- else
+ else if (for_file) {
+ content_type = g_strdup(libbalsa_vfs_get_mime_type(for_file));
+ filename = libbalsa_vfs_get_uri(for_file);
+ } else
content_type = g_strdup("application/octet-stream");
#ifdef HAVE_GNOME
Modified: trunk/libbalsa/files.h
==============================================================================
--- trunk/libbalsa/files.h (original)
+++ trunk/libbalsa/files.h Fri Apr 25 18:19:30 2008
@@ -27,6 +27,7 @@
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
+#include "libbalsa-vfs.h"
/* filename is the filename (naw!)
* splice is what to put in between the prefix and the filename, if desired
@@ -43,7 +44,7 @@
#define balsa_pixmap_finder_no_warn(filename) \
(balsa_file_finder((filename), "pixmaps", NULL, FALSE))
-GdkPixbuf *libbalsa_icon_finder(const char *mime_type, const char *filename,
+GdkPixbuf *libbalsa_icon_finder(const char *mime_type, const LibbalsaVfs * for_file,
gchar** used_type, GtkIconSize size);
void libbalsa_fill_vfs_menu_by_content_type(GtkMenu * menu,
Added: trunk/libbalsa/libbalsa-vfs.c
==============================================================================
--- (empty file)
+++ trunk/libbalsa/libbalsa-vfs.c Fri Apr 25 18:19:30 2008
@@ -0,0 +1,728 @@
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/*
+ * libbalsa vfs glue layer library
+ * Copyright (C) 2008 Albrecht Dreß<albrecht dress arcor de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <gmime/gmime.h>
+#include "gmime-stream-gnome-vfs.h"
+#include "misc.h"
+#include "libbalsa-vfs.h"
+
+
+#ifdef HAVE_GNOME
+# include <libgnomevfs/gnome-vfs.h>
+# define USE_GNOME_VFS 1
+#else
+# undef USE_GNOME_VFS
+#endif
+
+
+#define LIBBALSA_VFS_ERROR_QUARK (g_quark_from_static_string("libbalsa-vfs"))
+
+
+struct _LibbalsaVfsPriv {
+ gchar * file_uri;
+ gchar * file_utf8;
+ gchar * folder_uri;
+ gchar * mime_type;
+ gchar * charset;
+ LibBalsaTextAttribute text_attr;
+#ifdef USE_GNOME_VFS
+ GnomeVFSURI * gvfs_uri;
+ GnomeVFSFileInfo * info;
+#else
+ gchar * local_name;
+#endif
+};
+
+
+static GObjectClass *libbalsa_vfs_parent_class = NULL;
+
+
+static void libbalsa_vfs_class_init(LibbalsaVfsClass * klass);
+static void libbalsa_vfs_init(LibbalsaVfs * self);
+static void libbalsa_vfs_finalize(LibbalsaVfs * self);
+
+
+gboolean
+libbalsa_vfs_local_only(void)
+{
+#ifdef USE_GNOME_VFS
+ return FALSE;
+#else
+ return TRUE;
+#endif
+}
+
+
+GType
+libbalsa_vfs_get_type(void)
+{
+ static GType libbalsa_vfs_type = 0;
+
+ if (!libbalsa_vfs_type) {
+ static const GTypeInfo libbalsa_vfs_type_info = {
+ sizeof(LibbalsaVfsClass), /* class_size */
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) libbalsa_vfs_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(LibbalsaVfs), /* instance_size */
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) libbalsa_vfs_init, /* instance_init */
+ /* no value_table */
+ };
+
+ libbalsa_vfs_type =
+ g_type_register_static(G_TYPE_OBJECT, "LibbalsaVfs",
+ &libbalsa_vfs_type_info, 0);
+ }
+
+ return libbalsa_vfs_type;
+}
+
+
+static void
+libbalsa_vfs_class_init(LibbalsaVfsClass * klass)
+{
+ GObjectClass *gobject_klass = G_OBJECT_CLASS(klass);
+
+ libbalsa_vfs_parent_class = g_type_class_peek(G_TYPE_OBJECT);
+ gobject_klass->finalize =
+ (GObjectFinalizeFunc) libbalsa_vfs_finalize;
+}
+
+
+static void
+libbalsa_vfs_init(LibbalsaVfs * self)
+{
+ self->priv = NULL;
+}
+
+
+static void
+libbalsa_vfs_finalize(LibbalsaVfs * self)
+{
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_if_fail(self != NULL);
+ priv = self->priv;
+
+ if (priv) {
+ g_free(priv->file_uri);
+ g_free(priv->file_utf8);
+ g_free(priv->folder_uri);
+ g_free(priv->mime_type);
+ g_free(priv->charset);
+#ifdef USE_GNOME_VFS
+ if (priv->gvfs_uri)
+ gnome_vfs_uri_unref(priv->gvfs_uri);
+ if (priv->info)
+ gnome_vfs_file_info_unref(priv->info);
+#else
+ g_free(priv->local_name);
+#endif
+ g_free(priv);
+ }
+
+ libbalsa_vfs_parent_class->finalize(G_OBJECT(self));
+}
+
+
+LibbalsaVfs *
+libbalsa_vfs_new(void)
+{
+ return LIBBALSA_VFS(g_object_new(LIBBALSA_TYPE_VFS, NULL));
+}
+
+
+LibbalsaVfs *
+libbalsa_vfs_new_from_uri(const gchar * uri)
+{
+ LibbalsaVfs * retval;
+
+ g_return_val_if_fail(uri, NULL);
+ if (!(retval = libbalsa_vfs_new()))
+ return NULL;
+
+ if (!(retval->priv = g_new0(struct _LibbalsaVfsPriv, 1))) {
+ g_object_unref(G_OBJECT(retval));
+ return NULL;
+ }
+ retval->priv->text_attr = (LibBalsaTextAttribute) -1;
+
+ retval->priv->file_uri = g_strdup(uri);
+#ifdef USE_GNOME_VFS
+ retval->priv->gvfs_uri = gnome_vfs_uri_new(uri);
+ if (!retval->priv->gvfs_uri)
+ g_message(_("Failed to convert %s to a Gnome VFS URI"), uri);
+#else
+ retval->priv->local_name = g_filename_from_uri(uri, NULL, NULL);
+#endif
+
+ return retval;
+}
+
+
+/* create a new LibbalsaVfs object by appending text to the existing object
+ * file (note: text is in utf8, not escaped) */
+LibbalsaVfs *
+libbalsa_vfs_append(const LibbalsaVfs * file, const gchar * text)
+{
+ gchar * p;
+ gchar * q;
+ LibbalsaVfs * retval;
+
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ g_return_val_if_fail(file->priv->file_uri, NULL);
+ g_return_val_if_fail(text, NULL);
+
+ /* fake an absolute file name which we can convert to an uri */
+ p = g_strconcat("/", text, NULL);
+ q = g_filename_to_uri(p, NULL, NULL);
+ g_free(p);
+ if (!q)
+ return NULL;
+
+ /* append to the existing uri and create the new object from it */
+ p = g_strconcat(file->priv->file_uri, q + 8, NULL);
+ g_free(q);
+ retval = libbalsa_vfs_new_from_uri(p);
+ g_free(p);
+ return retval;
+}
+
+
+/* create a new LibbalsaVfs object by appending filename to the existing
+ * object dir which describes a folder (note: filename is in utf8, not
+ * escaped) */
+LibbalsaVfs *
+libbalsa_vfs_dir_append(const LibbalsaVfs * dir, const gchar * filename)
+{
+ gchar * p;
+ gchar * q;
+ LibbalsaVfs * retval;
+
+ g_return_val_if_fail(dir, NULL);
+ g_return_val_if_fail(dir->priv, NULL);
+ g_return_val_if_fail(dir->priv->file_uri, NULL);
+ g_return_val_if_fail(filename, NULL);
+
+ /* fake an absolute file name which we can convert to an uri */
+ p = g_strconcat("/", filename, NULL);
+ q = g_filename_to_uri(p, NULL, NULL);
+ g_free(p);
+ if (!q)
+ return NULL;
+
+ /* append to the existing uri and create the new object from it */
+ p = g_strconcat(dir->priv->file_uri, q + 7, NULL);
+ g_free(q);
+ retval = libbalsa_vfs_new_from_uri(p);
+ g_free(p);
+ return retval;
+}
+
+
+/* return the text uri of the passed file, removing the last component */
+const gchar *
+libbalsa_vfs_get_folder(const LibbalsaVfs * file)
+{
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, NULL);
+
+ if (!priv->folder_uri) {
+ gchar * p;
+
+ if ((priv->folder_uri = g_strdup(priv->file_uri)) &&
+ (p = g_utf8_strrchr(priv->folder_uri, -1, g_utf8_get_char("/"))))
+ *p = '\0';
+ }
+
+ return priv->folder_uri;
+}
+
+
+/* return the text uri of the passed file */
+const gchar *
+libbalsa_vfs_get_uri(const LibbalsaVfs * file)
+{
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ g_return_val_if_fail(file->priv->file_uri, NULL);
+
+ return file->priv->file_uri;
+}
+
+
+/* return the text uri of the passed file as utf8 string (%xx replaced) */
+const gchar *
+libbalsa_vfs_get_uri_utf8(const LibbalsaVfs * file)
+{
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, NULL);
+
+ if (!priv->file_utf8) {
+ gchar * p;
+ gchar * q;
+
+ if (!(p = priv->file_utf8 = g_malloc(strlen(priv->file_uri) + 1)))
+ return NULL;
+ q = priv->file_uri;
+ while (*q != '\0') {
+ if (*q == '%') {
+ if (g_ascii_isxdigit(q[1]) && g_ascii_isxdigit(q[2])) {
+ gint val = (g_ascii_xdigit_value(q[1]) << 4) +
+ g_ascii_xdigit_value(q[2]);
+ *p++ = (gchar) val;
+ q += 3;
+ } else
+ *p++ = *q++; /* hmmm - shouldn't happen! */
+ } else
+ *p++ = *q++;
+ }
+ *p = '\0';
+ }
+
+ return priv->file_utf8;
+}
+
+
+const gchar *
+libbalsa_vfs_get_basename_utf8(const LibbalsaVfs * file)
+{
+ const gchar * uri_utf8 = libbalsa_vfs_get_uri_utf8(file);
+ const gchar * p;
+
+ if (uri_utf8 &&
+ (p = g_utf8_strrchr(uri_utf8, -1, g_utf8_get_char("/"))))
+ return p + 1;
+ else
+ return NULL;
+}
+
+
+const gchar *
+libbalsa_vfs_get_mime_type(const LibbalsaVfs * file)
+{
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, NULL);
+
+ if (!priv->mime_type) {
+#ifdef USE_GNOME_VFS
+ /* use GnomeVFS to determine the mime type of the file */
+ g_return_val_if_fail(priv->gvfs_uri, FALSE);
+
+ if (!priv->info)
+ priv->info = gnome_vfs_file_info_new();
+
+ if (priv->info) {
+ if ((priv->info->valid_fields &
+ GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) == 0)
+ gnome_vfs_get_file_info_uri(priv->gvfs_uri, priv->info,
+ GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
+ GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE |
+ GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+ if ((priv->info->valid_fields &
+ GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE) != 0)
+ priv->mime_type = g_strdup(gnome_vfs_file_info_get_mime_type(priv->info));
+ }
+
+ /* always fall back to application/octet-stream */
+ if (!priv->mime_type)
+#endif
+ priv->mime_type = g_strdup("application/octet-stream");
+ }
+
+ return priv->mime_type;
+}
+
+
+const gchar *
+libbalsa_vfs_get_charset(const LibbalsaVfs * file)
+{
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, NULL);
+
+ if (!priv->charset && priv->text_attr == (LibBalsaTextAttribute) -1) {
+ libbalsa_vfs_get_text_attr(file);
+
+ if (!(priv->text_attr & LIBBALSA_TEXT_HI_BIT))
+ priv->charset = g_strdup("us-ascii");
+ else if (priv->text_attr & LIBBALSA_TEXT_HI_UTF8)
+ priv->charset = g_strdup("utf-8");
+ }
+
+ return priv->charset;
+}
+
+
+LibBalsaTextAttribute
+libbalsa_vfs_get_text_attr(const LibbalsaVfs * file)
+{
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, 0);
+ g_return_val_if_fail(file->priv, 0);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, 0);
+
+ if (priv->text_attr == (LibBalsaTextAttribute) -1) {
+#ifdef USE_GNOME_VFS
+ GnomeVFSHandle *handle;
+
+ /* use GnomeVFS to determine the text attributes of the file */
+ g_return_val_if_fail(priv->gvfs_uri, 0);
+ priv->text_attr = 0;
+
+ /* read and check - see libbalsa_text_attr_file() */
+ if (gnome_vfs_open_uri(&handle, priv->gvfs_uri, GNOME_VFS_OPEN_READ) ==
+ GNOME_VFS_OK) {
+ gchar buf[1024];
+ gchar *new_chars = buf;
+ gboolean has_esc = FALSE;
+ gboolean has_hi_bit = FALSE;
+ gboolean has_hi_ctrl = FALSE;
+ gboolean is_utf8 = TRUE;
+ GnomeVFSFileSize bytes_read;
+
+ while ((is_utf8 || (!has_esc || !has_hi_bit || !has_hi_ctrl)) &&
+ gnome_vfs_read(handle, new_chars, (sizeof buf) - (new_chars - buf) - 1,
+ &bytes_read) == GNOME_VFS_OK) {
+ new_chars[bytes_read] = '\0';
+
+ if (!has_esc || !has_hi_bit || !has_hi_ctrl) {
+ guchar * p;
+
+ for (p = (guchar *) new_chars; *p; p++)
+ if (*p == 0x1b)
+ has_esc = TRUE;
+ else if (*p >= 0x80) {
+ has_hi_bit = TRUE;
+ if (*p <= 0x9f)
+ has_hi_ctrl = TRUE;
+ }
+ }
+
+ if (is_utf8) {
+ const gchar *end;
+
+ new_chars = buf;
+ if (!g_utf8_validate(buf, -1, &end)) {
+ if (g_utf8_get_char_validated(end, -1) == (gunichar) (-1))
+ is_utf8 = FALSE;
+ else
+ /* copy any remaining bytes, including the
+ * terminating '\0', to start of buffer */
+ while ((*new_chars = *end++) != '\0')
+ new_chars++;
+ }
+ }
+ }
+
+ gnome_vfs_close(handle);
+
+ if (has_esc)
+ priv->text_attr |= LIBBALSA_TEXT_ESC;
+ if (has_hi_bit)
+ priv->text_attr |= LIBBALSA_TEXT_HI_BIT;
+ if (has_hi_ctrl)
+ priv->text_attr |= LIBBALSA_TEXT_HI_CTRL;
+ if (is_utf8 && has_hi_bit)
+ priv->text_attr |= LIBBALSA_TEXT_HI_UTF8;
+ }
+#else
+ /* use function from misc to get the text attributes */
+ g_return_val_if_fail(priv->local_name, 0);
+
+ priv->text_attr = libbalsa_text_attr_file(priv->local_name);
+#endif
+ }
+
+ return priv->text_attr;
+}
+
+
+gsize
+libbalsa_vfs_get_size(const LibbalsaVfs * file)
+{
+#ifndef USE_GNOME_VFS
+ struct stat s;
+#endif
+ gsize retval = 0;
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, 0);
+ g_return_val_if_fail(file->priv, 0);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, 0);
+
+#ifdef USE_GNOME_VFS
+ /* use GnomeVFS to determine the size of the file */
+ g_return_val_if_fail(priv->gvfs_uri, 0);
+
+ if (!priv->info)
+ priv->info = gnome_vfs_file_info_new();
+
+ if (priv->info) {
+ if ((priv->info->valid_fields &
+ GNOME_VFS_FILE_INFO_FIELDS_SIZE) == 0)
+ gnome_vfs_get_file_info_uri(priv->gvfs_uri, priv->info,
+ GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS |
+ GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+ if ((priv->info->valid_fields &
+ GNOME_VFS_FILE_INFO_FIELDS_SIZE) != 0)
+ retval = (gsize) priv->info->size;
+ }
+#else
+ /* call stat on the file to get the size */
+ g_return_val_if_fail(priv->local_name, 0);
+
+ if (g_stat(priv->local_name, &s) == 0)
+ retval = (gsize) s.st_size;
+#endif
+
+ return retval;
+}
+
+
+/* get a GMime stream for the passed file, either read-only or in
+ * read-write mode */
+GMimeStream *
+libbalsa_vfs_create_stream(const LibbalsaVfs * file, mode_t mode,
+ gboolean rdwr, GError ** err)
+{
+#ifdef USE_GNOME_VFS
+ GnomeVFSOpenMode openmode = GNOME_VFS_OPEN_RANDOM | GNOME_VFS_OPEN_READ;
+ GnomeVFSHandle * handle;
+ GnomeVFSResult result;
+#else
+ int fd;
+ int flags = O_EXCL;
+#endif
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, NULL);
+ g_return_val_if_fail(file->priv, NULL);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, NULL);
+
+#ifdef USE_GNOME_VFS
+ /* use GnomeVFS to create a GMime Gnome VFS stream */
+ g_return_val_if_fail(priv->gvfs_uri, NULL);
+
+ if (rdwr) {
+ openmode |= GNOME_VFS_OPEN_WRITE;
+ result = gnome_vfs_create_uri(&handle, priv->gvfs_uri,
+ openmode, TRUE, mode);
+ } else
+ result = gnome_vfs_open_uri(&handle, priv->gvfs_uri, openmode);
+ if (result != GNOME_VFS_OK) {
+ g_set_error(err, LIBBALSA_ERROR_QUARK, result,
+ gnome_vfs_result_to_string(result));
+ return NULL;
+ }
+
+ return g_mime_stream_gvfs_new(handle);
+#else
+ /* use libc to create a GMime file system stream */
+ g_return_val_if_fail(priv->local_name, NULL);
+
+ flags |= rdwr ? O_CREAT | O_RDWR : O_RDONLY;
+
+#ifdef O_NOFOLLOW
+ flags |= O_NOFOLLOW;
+#endif
+
+ if ((fd = libbalsa_safe_open(priv->local_name, flags, mode, err)) < 0)
+ return NULL;
+
+ return g_mime_stream_fs_new(fd);
+#endif
+}
+
+
+/* return TRUE if the passed file exists */
+gboolean
+libbalsa_vfs_file_exists(const LibbalsaVfs * file)
+{
+ gboolean result = FALSE;
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, FALSE);
+ g_return_val_if_fail(file->priv, FALSE);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, FALSE);
+
+#ifdef USE_GNOME_VFS
+ /* use GnomeVFS to check if the file exists */
+ g_return_val_if_fail(priv->gvfs_uri, FALSE);
+
+ if (!priv->info)
+ priv->info = gnome_vfs_file_info_new();
+
+ if (priv->info) {
+ if ((priv->info->valid_fields &
+ GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS) == 0)
+ gnome_vfs_get_file_info_uri(priv->gvfs_uri, priv->info,
+ GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS |
+ GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+ if ((priv->info->valid_fields &
+ GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS))
+ result = TRUE;
+ }
+#else
+ /* use g_access to check if the (local) file exists */
+ g_return_val_if_fail(priv->local_name, FALSE);
+
+ result = (g_access(priv->local_name, F_OK) == 0);
+#endif
+
+ return result;
+}
+
+
+gboolean
+libbalsa_vfs_is_regular_file(const LibbalsaVfs * file, GError **err)
+{
+#ifndef USE_GNOME_VFS
+ struct stat s;
+#endif
+ gboolean result = FALSE;
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, FALSE);
+ g_return_val_if_fail(file->priv, FALSE);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, FALSE);
+
+#ifdef USE_GNOME_VFS
+ /* use GnomeVFS to check if the file is a regular one which can be read */
+ g_return_val_if_fail(priv->gvfs_uri, FALSE);
+
+ if (!priv->info)
+ priv->info = gnome_vfs_file_info_new();
+
+ if (priv->info) {
+ if ((priv->info->valid_fields &
+ (GNOME_VFS_FILE_INFO_FIELDS_TYPE |
+ GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS)) == 0)
+ gnome_vfs_get_file_info_uri(priv->gvfs_uri, priv->info,
+ GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS |
+ GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+ g_message("fields = %x", priv->info->valid_fields);
+ if ((priv->info->valid_fields &
+ (GNOME_VFS_FILE_INFO_FIELDS_TYPE |
+ GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS)) !=
+ (GNOME_VFS_FILE_INFO_FIELDS_TYPE |
+ GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS))
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, -1,
+ _("cannot read file information"));
+ else if (priv->info->type != GNOME_VFS_FILE_TYPE_REGULAR)
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, -1,
+ _("not a regular file"));
+ else if ((priv->info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_ACCESS) &&
+ !(priv->info->permissions & GNOME_VFS_PERM_ACCESS_READABLE))
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, -1, _("cannot read"));
+ else
+ result = TRUE;
+ }
+#else
+ /* use libc to check if the file is a regular one which can be read */
+ g_return_val_if_fail(priv->local_name, FALSE);
+
+ if (g_stat(priv->local_name, &s) != 0)
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, errno,
+ g_strerror(errno));
+ else if (!S_ISREG(s.st_mode))
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, -1, _("not a regular file"));
+ else if (g_access(priv->local_name, R_OK) != 0)
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, -1, _("cannot read"));
+ else
+ result = TRUE;
+#endif
+
+ return result;
+}
+
+
+/* unlink the passed file, return 0 on success and -1 on error */
+gint
+libbalsa_vfs_file_unlink(const LibbalsaVfs * file, GError **err)
+{
+#ifdef USE_GNOME_VFS
+ GnomeVFSResult vfs_res;
+#endif
+ gint result = -1;
+ struct _LibbalsaVfsPriv * priv;
+
+ g_return_val_if_fail(file, -1);
+ g_return_val_if_fail(file->priv, -1);
+ priv = file->priv;
+ g_return_val_if_fail(priv->file_uri, -1);
+
+#ifdef USE_GNOME_VFS
+ /* use GnomeVFS to unlink the file */
+ g_return_val_if_fail(priv->gvfs_uri, -1);
+
+ if ((vfs_res = gnome_vfs_unlink_from_uri(priv->gvfs_uri)) != GNOME_VFS_OK)
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, vfs_res,
+ gnome_vfs_result_to_string(vfs_res));
+ else
+ result = 0;
+#else
+ /* use g_unlink to unlink the (local) file */
+ g_return_val_if_fail(priv->local_name, -1);
+
+ result = g_unlink(priv->local_name);
+ if (result != 0)
+ g_set_error(err, LIBBALSA_VFS_ERROR_QUARK, errno,
+ g_strerror(errno));
+#endif
+
+ return result;
+}
Added: trunk/libbalsa/libbalsa-vfs.h
==============================================================================
--- (empty file)
+++ trunk/libbalsa/libbalsa-vfs.h Fri Apr 25 18:19:30 2008
@@ -0,0 +1,258 @@
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/*
+ * libbalsa vfs glue layer library
+ * Copyright (C) 2008 Albrecht Dreß<albrecht dress arcor de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __LIBBALSA_VFS_H__
+#define __LIBBALSA_VFS_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmime/gmime.h>
+#include "misc.h"
+
+
+G_BEGIN_DECLS
+
+
+/* a vfs file description as GObject */
+#define LIBBALSA_TYPE_VFS (libbalsa_vfs_get_type())
+#define LIBBALSA_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LIBBALSA_TYPE_VFS, LibbalsaVfs))
+#define LIBBALSA_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), LIBBALSA_TYPE_VFS, LibbalsaVfsClass))
+#define LIBBALSA_IS_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LIBBALSA_TYPE_VFS))
+#define LIBBALSA_IS_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LIBBALSA_TYPE_VFS))
+#define LIBBALSA_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LIBBALSA_TYPE_VFS, LibbalsaVfsClass))
+
+typedef struct _LibbalsaVfs LibbalsaVfs;
+typedef struct _LibbalsaVfsClass LibbalsaVfsClass;
+
+
+struct _LibbalsaVfs {
+ GObject parent;
+
+ struct _LibbalsaVfsPriv * priv;
+};
+
+struct _LibbalsaVfsClass {
+ GObjectClass parent;
+};
+
+gboolean libbalsa_vfs_local_only(void);
+
+GType libbalsa_vfs_get_type(void);
+LibbalsaVfs * libbalsa_vfs_new(void);
+LibbalsaVfs * libbalsa_vfs_new_from_uri(const gchar * uri);
+LibbalsaVfs * libbalsa_vfs_append(const LibbalsaVfs * file,
+ const gchar * text);
+LibbalsaVfs * libbalsa_vfs_dir_append(const LibbalsaVfs * dir,
+ const gchar * filename);
+const gchar * libbalsa_vfs_get_folder(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_uri(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_uri_utf8(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_basename_utf8(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_mime_type(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_charset(const LibbalsaVfs * file);
+LibBalsaTextAttribute libbalsa_vfs_get_text_attr(const LibbalsaVfs * file);
+gsize libbalsa_vfs_get_size(const LibbalsaVfs * file);
+GMimeStream * libbalsa_vfs_create_stream(const LibbalsaVfs * file,
+ mode_t mode,
+ gboolean rdwr,
+ GError ** err);
+gboolean libbalsa_vfs_file_exists(const LibbalsaVfs * file);
+gboolean libbalsa_vfs_is_regular_file(const LibbalsaVfs * file, GError **err);
+gint libbalsa_vfs_file_unlink(const LibbalsaVfs * file, GError **err);
+
+
+G_END_DECLS
+
+
+#endif /* __LIBBALSA_VFS_H__ */
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/*
+ * libbalsa vfs glue layer library
+ * Copyright (C) 2008 Albrecht Dreß<albrecht dress arcor de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __LIBBALSA_VFS_H__
+#define __LIBBALSA_VFS_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmime/gmime.h>
+#include "misc.h"
+
+
+G_BEGIN_DECLS
+
+
+/* a vfs file description as GObject */
+#define LIBBALSA_TYPE_VFS (libbalsa_vfs_get_type())
+#define LIBBALSA_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LIBBALSA_TYPE_VFS, LibbalsaVfs))
+#define LIBBALSA_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), LIBBALSA_TYPE_VFS, LibbalsaVfsClass))
+#define LIBBALSA_IS_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LIBBALSA_TYPE_VFS))
+#define LIBBALSA_IS_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LIBBALSA_TYPE_VFS))
+#define LIBBALSA_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LIBBALSA_TYPE_VFS, LibbalsaVfsClass))
+
+typedef struct _LibbalsaVfs LibbalsaVfs;
+typedef struct _LibbalsaVfsClass LibbalsaVfsClass;
+
+
+struct _LibbalsaVfs {
+ GObject parent;
+
+ struct _LibbalsaVfsPriv * priv;
+};
+
+struct _LibbalsaVfsClass {
+ GObjectClass parent;
+};
+
+gboolean libbalsa_vfs_local_only(void);
+
+GType libbalsa_vfs_get_type(void);
+LibbalsaVfs * libbalsa_vfs_new(void);
+LibbalsaVfs * libbalsa_vfs_new_from_uri(const gchar * uri);
+LibbalsaVfs * libbalsa_vfs_append(const LibbalsaVfs * file,
+ const gchar * text);
+LibbalsaVfs * libbalsa_vfs_dir_append(const LibbalsaVfs * dir,
+ const gchar * filename);
+const gchar * libbalsa_vfs_get_folder(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_uri(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_uri_utf8(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_basename_utf8(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_mime_type(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_charset(const LibbalsaVfs * file);
+LibBalsaTextAttribute libbalsa_vfs_get_text_attr(const LibbalsaVfs * file);
+gsize libbalsa_vfs_get_size(const LibbalsaVfs * file);
+GMimeStream * libbalsa_vfs_create_stream(const LibbalsaVfs * file,
+ mode_t mode,
+ gboolean rdwr,
+ GError ** err);
+gboolean libbalsa_vfs_file_exists(const LibbalsaVfs * file);
+gboolean libbalsa_vfs_is_regular_file(const LibbalsaVfs * file, GError **err);
+gint libbalsa_vfs_file_unlink(const LibbalsaVfs * file, GError **err);
+
+
+G_END_DECLS
+
+
+#endif /* __LIBBALSA_VFS_H__ */
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/*
+ * libbalsa vfs glue layer library
+ * Copyright (C) 2008 Albrecht Dreß<albrecht dress arcor de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __LIBBALSA_VFS_H__
+#define __LIBBALSA_VFS_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gmime/gmime.h>
+#include "misc.h"
+
+
+G_BEGIN_DECLS
+
+
+/* a vfs file description as GObject */
+#define LIBBALSA_TYPE_VFS (libbalsa_vfs_get_type())
+#define LIBBALSA_VFS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LIBBALSA_TYPE_VFS, LibbalsaVfs))
+#define LIBBALSA_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), LIBBALSA_TYPE_VFS, LibbalsaVfsClass))
+#define LIBBALSA_IS_VFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LIBBALSA_TYPE_VFS))
+#define LIBBALSA_IS_VFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LIBBALSA_TYPE_VFS))
+#define LIBBALSA_VFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LIBBALSA_TYPE_VFS, LibbalsaVfsClass))
+
+typedef struct _LibbalsaVfs LibbalsaVfs;
+typedef struct _LibbalsaVfsClass LibbalsaVfsClass;
+
+
+struct _LibbalsaVfs {
+ GObject parent;
+
+ struct _LibbalsaVfsPriv * priv;
+};
+
+struct _LibbalsaVfsClass {
+ GObjectClass parent;
+};
+
+gboolean libbalsa_vfs_local_only(void);
+
+GType libbalsa_vfs_get_type(void);
+LibbalsaVfs * libbalsa_vfs_new(void);
+LibbalsaVfs * libbalsa_vfs_new_from_uri(const gchar * uri);
+LibbalsaVfs * libbalsa_vfs_append(const LibbalsaVfs * file,
+ const gchar * text);
+LibbalsaVfs * libbalsa_vfs_dir_append(const LibbalsaVfs * dir,
+ const gchar * filename);
+const gchar * libbalsa_vfs_get_folder(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_uri(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_uri_utf8(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_basename_utf8(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_mime_type(const LibbalsaVfs * file);
+const gchar * libbalsa_vfs_get_charset(const LibbalsaVfs * file);
+LibBalsaTextAttribute libbalsa_vfs_get_text_attr(const LibbalsaVfs * file);
+gsize libbalsa_vfs_get_size(const LibbalsaVfs * file);
+GMimeStream * libbalsa_vfs_create_stream(const LibbalsaVfs * file,
+ mode_t mode,
+ gboolean rdwr,
+ GError ** err);
+gboolean libbalsa_vfs_file_exists(const LibbalsaVfs * file);
+gboolean libbalsa_vfs_is_regular_file(const LibbalsaVfs * file, GError **err);
+gint libbalsa_vfs_file_unlink(const LibbalsaVfs * file, GError **err);
+
+
+G_END_DECLS
+
+
+#endif /* __LIBBALSA_VFS_H__ */
Modified: trunk/libbalsa/message.h
==============================================================================
--- trunk/libbalsa/message.h (original)
+++ trunk/libbalsa/message.h Fri Apr 25 18:19:30 2008
@@ -288,12 +288,6 @@
gboolean fetch_all_headers);
void libbalsa_message_body_unref(LibBalsaMessage * message);
-gboolean libbalsa_message_postpone(LibBalsaMessage * message,
- LibBalsaMailbox * draftbox,
- LibBalsaMessage * reply_message,
- gchar ** extra_headers,
- gboolean flow);
-
/*
* misc message releated functions
*/
Modified: trunk/libbalsa/misc.c
==============================================================================
--- trunk/libbalsa/misc.c (original)
+++ trunk/libbalsa/misc.c Fri Apr 25 18:19:30 2008
@@ -53,36 +53,6 @@
LibBalsaCodeset Codeset);
static int getdnsdomainname(char *s, size_t l);
-/* libbalsa_lookup_mime_type:
- find out mime type of a file. Must work for both relative and absolute
- paths.
-*/
-gchar*
-libbalsa_lookup_mime_type(const gchar * path)
-{
-#ifdef HAVE_GNOME
- GnomeVFSFileInfo* vi = gnome_vfs_file_info_new();
- gchar* uri, *mime_type;
-
- if(g_path_is_absolute(path))
- uri = g_strconcat("file://", path, NULL);
- else {
- gchar* curr_dir = g_get_current_dir();
- uri = g_strconcat("file://", curr_dir, "/", path, NULL);
- g_free(curr_dir);
- }
- gnome_vfs_get_file_info (uri, vi,
- GNOME_VFS_FILE_INFO_GET_MIME_TYPE
- | GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
- g_free(uri);
- mime_type = g_strdup(gnome_vfs_file_info_get_mime_type(vi));
- gnome_vfs_file_info_unref(vi);
- return mime_type ? mime_type : g_strdup("application/octet-stream");
-#else
- return g_strdup("application/octet-stream");
-#endif/* HAVE_GNOME */
-}
-
gchar *
libbalsa_get_hostname(void)
{
@@ -829,43 +799,28 @@
return attr;
}
-/* Check whether a file is all ascii or utf-8, and return charset
- * accordingly (NULL if it's neither).
- * This function is called only as a last resort when a message is being
- * prepared for sending. The charset should always be set when the file
- * is being attached.
- */
-const gchar *
-libbalsa_file_get_charset(const gchar * filename)
-{
- LibBalsaTextAttribute attr = libbalsa_text_attr_file(filename);
-
- if (!(attr & LIBBALSA_TEXT_HI_BIT))
- return "us-ascii";
- if (attr & LIBBALSA_TEXT_HI_UTF8)
- return "utf-8";
- return NULL;
-}
-
#define compare_stat(osb, nsb) ( (osb.st_dev != nsb.st_dev || osb.st_ino != nsb.st_ino || osb.st_rdev != nsb.st_rdev) ? -1 : 0 )
int
-libbalsa_safe_open (const char *path, int flags, mode_t mode)
+libbalsa_safe_open (const char *path, int flags, mode_t mode, GError **err)
{
struct stat osb, nsb;
int fd;
- if ((fd = open (path, flags, mode)) < 0)
- return fd;
+ if ((fd = open (path, flags, mode)) < 0) {
+ g_set_error(err, LIBBALSA_ERROR_QUARK, errno,
+ _("Cannot open %s: %s"), path, g_strerror(errno));
+ return fd;
+ }
/* make sure the file is not symlink */
if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
- compare_stat(osb, nsb) == -1)
- {
- g_warning("safe_open(): %s is a symlink!\n", path);
- close (fd);
- return (-1);
- }
+ compare_stat(osb, nsb) == -1) {
+ close (fd);
+ g_set_error(err, LIBBALSA_ERROR_QUARK, errno,
+ _("Cannot open %s: is a symbolic link"), path);
+ return (-1);
+ }
return (fd);
}
Modified: trunk/libbalsa/misc.h
==============================================================================
--- trunk/libbalsa/misc.h (original)
+++ trunk/libbalsa/misc.h Fri Apr 25 18:19:30 2008
@@ -96,13 +96,12 @@
GString *ml_url_buffer;
};
+#define LIBBALSA_ERROR_QUARK (g_quark_from_static_string("libbalsa"))
+
extern LibBalsaCodesetInfo libbalsa_codeset_info[];
GtkWidget *libbalsa_charset_button_new(void);
LibBalsaTextAttribute libbalsa_text_attr_string(const gchar * string);
LibBalsaTextAttribute libbalsa_text_attr_file(const gchar * filename);
-const gchar *libbalsa_file_get_charset(const gchar * filename);
-
-gchar *libbalsa_lookup_mime_type(const gchar * path);
size_t libbalsa_readfile(FILE * fp, char **buf);
size_t libbalsa_readfile_nostat(FILE * fp, char **buf);
@@ -153,7 +152,7 @@
guint * count, guint * index);
#endif /* USE_GREGEX */
-int libbalsa_safe_open (const char *path, int flags, mode_t mode);
+int libbalsa_safe_open (const char *path, int flags, mode_t mode, GError **err);
int libbalsa_lock_file (const char *path, int fd, int excl, int dot, int timeout);
int libbalsa_unlock_file (const char *path, int fd, int dot);
int libbalsa_safe_rename (const char *src, const char *target);
Modified: trunk/libbalsa/send.c
==============================================================================
--- trunk/libbalsa/send.c (original)
+++ trunk/libbalsa/send.c Fri Apr 25 18:19:30 2008
@@ -402,8 +402,8 @@
guint big_message;
#endif /* ESMTP */
gboolean rc;
- GError *err = NULL;
+ g_assert(error != NULL);
g_return_val_if_fail(message, LIBBALSA_MESSAGE_CREATE_ERROR);
if ((result = libbalsa_create_msg(message, flow, error)) !=
@@ -441,25 +441,18 @@
}
if (rc) {
message->mime_msg = mime_msgs[i];
- rc = libbalsa_message_copy(message, outbox, &err);
+ rc = libbalsa_message_copy(message, outbox, error);
}
g_object_unref(mime_msgs[i]);
}
g_free(mime_msgs);
message->mime_msg = mime_msg;
} else
- rc = libbalsa_message_copy(message, outbox, &err);
+ rc = libbalsa_message_copy(message, outbox, error);
#else /* ESMTP */
- rc = libbalsa_message_copy(message, outbox, &err);
+ rc = libbalsa_message_copy(message, outbox, error);
#endif /* ESMTP */
- if (!rc) {
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Copying message to outbox failed: %s"),
- err ? err->message : "?");
- g_clear_error(&err);
- }
-
return rc ? LIBBALSA_MESSAGE_CREATE_OK : LIBBALSA_MESSAGE_QUEUE_ERROR;
}
@@ -1617,11 +1610,11 @@
GMimeObject *mime_part;
mime_part=NULL;
- if (body->filename) {
+ if (body->file_uri || body->filename) {
if (body->content_type) {
mime_type = parse_content_type(body->content_type);
} else {
- gchar* mt = libbalsa_lookup_mime_type(body->filename);
+ gchar * mt = g_strdup(libbalsa_vfs_get_mime_type(body->file_uri));
mime_type = g_strsplit(mt,"/", 2);
g_free(mt);
}
@@ -1633,7 +1626,7 @@
g_mime_object_set_content_type(mime_part, content_type);
g_mime_part_set_encoding(GMIME_PART(mime_part),
GMIME_PART_ENCODING_7BIT);
- if(!strncmp( body->filename, "URL", 3 )) {
+ if (body->filename && !strncmp(body->filename, "URL", 3)) {
g_mime_object_set_content_type_parameter(mime_part,
"access-type", "URL");
g_mime_object_set_content_type_parameter(mime_part,
@@ -1642,18 +1635,32 @@
g_mime_object_set_content_type_parameter(mime_part,
"access-type", "local-file");
g_mime_object_set_content_type_parameter(mime_part,
- "name", body->filename);
+ "name", libbalsa_vfs_get_uri_utf8(body->file_uri));
}
lbs_set_content(GMIME_PART(mime_part),
"Note: this is _not_ the real body!\n");
} else if (g_ascii_strcasecmp(mime_type[0], "message") == 0) {
- int fd;
GMimeStream *stream;
GMimeParser *parser;
GMimeMessage *mime_message;
+ GError *err = NULL;
- fd = open(body->filename, O_RDONLY);
- stream = g_mime_stream_fs_new(fd);
+ stream = libbalsa_vfs_create_stream(body->file_uri, 0, FALSE, &err);
+ if(!stream) {
+ if(err) {
+ gchar *msg =
+ err->message
+ ? g_strdup_printf(_("Cannot read %s: %s"),
+ libbalsa_vfs_get_uri_utf8(body->file_uri),
+ err->message)
+ : g_strdup_printf(_("Cannot read %s"),
+ libbalsa_vfs_get_uri_utf8(body->file_uri));
+ g_set_error(error, err->domain, err->code, msg);
+ g_clear_error(&err);
+ g_free(msg);
+ }
+ return LIBBALSA_MESSAGE_CREATE_ERROR;
+ }
parser = g_mime_parser_new_with_stream(stream);
g_object_unref(stream);
mime_message = g_mime_parser_construct_message(parser);
@@ -1666,12 +1673,11 @@
const gchar *charset = NULL;
GMimeStream *stream;
GMimeDataWrapper *content;
- int fd;
- gchar *utf8name;
+ GError *err = NULL;
if (!strcasecmp(mime_type[0], "text")
&& !(charset = body->charset)) {
- charset = libbalsa_file_get_charset(body->filename);
+ charset = libbalsa_vfs_get_charset(body->file_uri);
if (!charset) {
static const gchar default_type[] =
"application/octet-stream";
@@ -1680,7 +1686,8 @@
_("Cannot determine charset "
"for text file `%s'; "
"sending as mime type `%s'"),
- body->filename, default_type);
+ libbalsa_vfs_get_uri_utf8(body->file_uri),
+ default_type);
g_strfreev(mime_type);
mime_type = g_strsplit(default_type, "/", 2);
}
@@ -1705,14 +1712,25 @@
charset);
}
- tmp = g_path_get_basename(body->filename);
- utf8name = g_filename_to_utf8(tmp, -1, NULL, NULL, NULL);
- g_free(tmp);
- g_mime_part_set_filename(GMIME_PART(mime_part), utf8name);
- g_free(utf8name);
-
- fd = open(body->filename, O_RDONLY);
- stream = g_mime_stream_fs_new(fd);
+ g_mime_part_set_filename(GMIME_PART(mime_part),
+ libbalsa_vfs_get_basename_utf8(body->file_uri));
+ stream = libbalsa_vfs_create_stream(body->file_uri, 0, FALSE, &err);
+ if(!stream) {
+ if(err) {
+ gchar *msg =
+ err->message
+ ? g_strdup_printf(_("Cannot read %s: %s"),
+ libbalsa_vfs_get_uri_utf8(body->file_uri),
+ err->message)
+ : g_strdup_printf(_("Cannot read %s"),
+ libbalsa_vfs_get_uri_utf8(body->file_uri));
+ g_set_error(error, err->domain, err->code, msg);
+ g_clear_error(&err);
+ g_free(msg);
+ }
+ g_object_unref(G_OBJECT(mime_part));
+ return LIBBALSA_MESSAGE_CREATE_ERROR;
+ }
content = g_mime_data_wrapper_new_with_stream(stream,
GMIME_PART_ENCODING_DEFAULT);
g_object_unref(stream);
@@ -1858,16 +1876,12 @@
libbalsa_message_postpone(LibBalsaMessage * message,
LibBalsaMailbox * draftbox,
LibBalsaMessage * reply_message,
- gchar ** extra_headers, gboolean flow)
+ gchar ** extra_headers, gboolean flow,
+ GError **error)
{
- gboolean retval;
- GError *err = NULL;
-
- /* in postpone mode no crypto operation is triggered, so we don't need to
- pass the error */
if (!message->mime_msg
&& libbalsa_message_create_mime_message(message, flow,
- TRUE, NULL) !=
+ TRUE, error) !=
LIBBALSA_MESSAGE_CREATE_OK)
return FALSE;
@@ -1879,16 +1893,7 @@
extra_headers[i + 1]);
}
- retval = libbalsa_message_copy(message, draftbox, &err);
-
- if (!retval) {
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Postponing message failed: %s"),
- err ? err->message : "?");
- g_clear_error(&err);
- }
-
- return retval;
+ return libbalsa_message_copy(message, draftbox, error);
}
Modified: trunk/libbalsa/send.h
==============================================================================
--- trunk/libbalsa/send.h (original)
+++ trunk/libbalsa/send.h Fri Apr 25 18:19:30 2008
@@ -39,6 +39,14 @@
LIBBALSA_MESSAGE_SERVER_ERROR
};
+gboolean libbalsa_message_postpone(LibBalsaMessage * message,
+ LibBalsaMailbox * draftbox,
+ LibBalsaMessage * reply_message,
+ gchar ** extra_headers,
+ gboolean flow,
+ GError **error);
+
+
#if ENABLE_ESMTP
#include <libesmtp.h>
Modified: trunk/src/balsa-message.c
==============================================================================
--- trunk/src/balsa-message.c (original)
+++ trunk/src/balsa-message.c Fri Apr 25 18:19:30 2008
@@ -47,6 +47,7 @@
#include "send.h"
#include "quote-color.h"
#include "sendmsg-window.h"
+#include "libbalsa-vfs.h"
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
@@ -1072,9 +1073,9 @@
bm->message = message = libbalsa_mailbox_get_message(mailbox, msgno);
if (!message) {
balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not access message %ld "
+ _("Could not access message %u "
"in mailbox \"%s\"."),
- msgno, mailbox->name);
+ (unsigned int) msgno, mailbox->name);
return FALSE;
}
@@ -1084,9 +1085,9 @@
g_object_unref(bm->message);
bm->message = NULL;
balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not access message %ld "
+ _("Could not access message %u "
"in mailbox \"%s\"."),
- msgno, mailbox->name);
+ (unsigned int) msgno, mailbox->name);
return FALSE;
}
@@ -1420,7 +1421,7 @@
#endif
if (!content_icon)
content_icon =
- libbalsa_icon_finder(content_type, body->filename, NULL,
+ libbalsa_icon_finder(content_type, NULL, NULL,
GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_tree_store_set (GTK_TREE_STORE(model), iter,
PART_INFO_COLUMN, info,
@@ -1432,7 +1433,7 @@
g_free(icon_title);
} else {
content_icon =
- libbalsa_icon_finder(content_type, body->filename, NULL,
+ libbalsa_icon_finder(content_type, NULL, NULL,
GTK_ICON_SIZE_LARGE_TOOLBAR);
gtk_tree_store_set (GTK_TREE_STORE(model), iter,
PART_INFO_COLUMN, NULL,
@@ -1649,30 +1650,38 @@
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
gtk_dialog_set_default_response(GTK_DIALOG(dump_dialog),
GTK_RESPONSE_CANCEL);
-
+ gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dump_dialog),
+ libbalsa_vfs_local_only());
if (balsa_app.save_dir)
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dump_dialog),
- balsa_app.save_dir);
+ gtk_file_chooser_set_current_folder_uri(GTK_FILE_CHOOSER(dump_dialog),
+ balsa_app.save_dir);
if (gtk_dialog_run(GTK_DIALOG(dump_dialog)) == GTK_RESPONSE_OK) {
- gchar *dirname =
- gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dump_dialog));
+ gchar *dir_name =
+ gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dump_dialog));
+ LibbalsaVfs * dir_uri;
+
+ g_message("store to URI: %s", dir_name);
+ if (!(dir_uri = libbalsa_vfs_new_from_uri(dir_name)))
+ balsa_information(LIBBALSA_INFORMATION_ERROR,
+ _("Could not create URI for %s"),
+ dir_name);
/* remember the folder */
g_free(balsa_app.save_dir);
- balsa_app.save_dir = g_strdup(dirname);
+ balsa_app.save_dir = dir_name;
/* save all parts without further user interaction */
info_list = g_list_first(info_list);
- while (info_list) {
+ while (dir_uri && info_list) {
BalsaPartInfo *info = BALSA_PART_INFO(info_list->data);
- gchar *save_name;
+ LibbalsaVfs * save_uri;
gboolean result;
GError *err = NULL;
if (info->body->filename)
- save_name =
- g_build_filename(dirname, info->body->filename, NULL);
+ save_uri =
+ libbalsa_vfs_dir_append(dir_uri, info->body->filename);
else {
gchar *cont_type =
libbalsa_message_body_get_mime_type(info->body);
@@ -1682,41 +1691,46 @@
g_strdelimit(cont_type, G_DIR_SEPARATOR_S, '-');
p = g_strdup_printf(_("%s message part"), cont_type);
g_free(cont_type);
- save_name = g_build_filename(dirname, p, NULL);
+ save_uri = libbalsa_vfs_dir_append(dir_uri, p);
g_free(p);
}
+ g_message("store to file: %s", libbalsa_vfs_get_uri_utf8(save_uri));
/* don't overwrite existing files, append (1), (2), ... instead */
- if (access(save_name, F_OK) == 0) {
+ if (libbalsa_vfs_file_exists(save_uri)) {
gint n = 1;
- gchar *base_name = save_name;
+ LibbalsaVfs * base_uri = save_uri;
- save_name = NULL;
+ save_uri = NULL;
do {
- g_free(save_name);
- save_name = g_strdup_printf("%s (%d)", base_name, n++);
- } while (access(save_name, F_OK) == 0);
- g_free(base_name);
+ gchar * ext = g_strdup_printf(" (%d)", n++);
+ if (save_uri)
+ g_object_unref(save_uri);
+ save_uri = libbalsa_vfs_append(base_uri, ext);
+ g_free(ext);
+ } while (libbalsa_vfs_file_exists(save_uri));
+ g_object_unref(base_uri);
}
+ g_message("store to file: %s", libbalsa_vfs_get_uri_utf8(save_uri));
/* try to save the file */
result =
- libbalsa_message_body_save(info->body, save_name,
- LIBBALSA_MESSAGE_BODY_UNSAFE,
- info->body->body_type ==
- LIBBALSA_MESSAGE_BODY_TYPE_TEXT,
- &err);
+ libbalsa_message_body_save_vfs(info->body, save_uri,
+ LIBBALSA_MESSAGE_BODY_UNSAFE,
+ info->body->body_type ==
+ LIBBALSA_MESSAGE_BODY_TYPE_TEXT,
+ &err);
if (!result)
balsa_information(LIBBALSA_INFORMATION_ERROR,
_("Could not save %s: %s"),
- save_name,
- err->message ?
+ libbalsa_vfs_get_uri_utf8(save_uri),
+ err && err->message ?
err->message : "Unknown error");
g_clear_error(&err);
- g_free(save_name);
+ g_object_unref(save_uri);
info_list = g_list_next(info_list);
}
- g_free(dirname);
+ g_object_unref(dir_uri);
}
gtk_widget_destroy(dump_dialog);
}
Modified: trunk/src/balsa-mime-widget-callbacks.c
==============================================================================
--- trunk/src/balsa-mime-widget-callbacks.c (original)
+++ trunk/src/balsa-mime-widget-callbacks.c Fri Apr 25 18:19:30 2008
@@ -25,6 +25,7 @@
#include "config.h"
#include "balsa-app.h"
#include <glib/gi18n.h>
+#include "libbalsa-vfs.h"
#include "balsa-message.h"
#include "balsa-mime-widget.h"
#include "balsa-mime-widget-callbacks.h"
@@ -136,7 +137,8 @@
{
gchar *cont_type, *title;
GtkWidget *save_dialog;
- gchar *filename;
+ gchar *file_uri;
+ LibbalsaVfs *save_file;
gboolean do_save;
GError *err = NULL;
@@ -156,12 +158,14 @@
g_free(title);
g_free(cont_type);
+ gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(save_dialog),
+ libbalsa_vfs_local_only());
if (balsa_app.save_dir)
- gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(save_dialog),
- balsa_app.save_dir);
+ gtk_file_chooser_set_current_folder_uri(GTK_FILE_CHOOSER(save_dialog),
+ balsa_app.save_dir);
if (mime_body->filename) {
- gchar *filename = g_strdup(mime_body->filename);
+ gchar * filename = g_strdup(mime_body->filename);
libbalsa_utf8_sanitize(&filename, balsa_app.convert_unknown_8bit,
NULL);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_dialog),
@@ -175,15 +179,23 @@
return;
}
- /* attempt to save the file */
- filename
- = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_dialog));
+ /* get the file name */
+ file_uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(save_dialog));
gtk_widget_destroy(save_dialog);
+ if (!(save_file = libbalsa_vfs_new_from_uri(file_uri))) {
+ balsa_information(LIBBALSA_INFORMATION_ERROR,
+ _("Could not construct uri from %s"),
+ file_uri);
+ g_free(file_uri);
+ return;
+ }
+ /* remember the folder uri */
g_free(balsa_app.save_dir);
- balsa_app.save_dir = g_path_get_dirname(filename);
+ balsa_app.save_dir = g_strdup(libbalsa_vfs_get_folder(save_file));
- if (access(filename, F_OK) == 0) {
+ /* get a confirmation to overwrite if the file exists */
+ if (libbalsa_vfs_file_exists(save_file)) {
GtkWidget *confirm;
/* File exists. check if they really want to overwrite */
@@ -196,19 +208,27 @@
(gtk_dialog_run(GTK_DIALOG(confirm)) == GTK_RESPONSE_YES);
gtk_widget_destroy(confirm);
if (do_save)
- unlink(filename);
+ if (libbalsa_vfs_file_unlink(save_file, &err) != 0)
+ balsa_information(LIBBALSA_INFORMATION_ERROR,
+ _("Unlink %s: %s"),
+ file_uri, err ? err->message : "Unknown error");
} else
do_save = TRUE;
- if (do_save)
- if (!libbalsa_message_body_save(mime_body, filename,
- LIBBALSA_MESSAGE_BODY_UNSAFE,
- mime_body->body_type ==
- LIBBALSA_MESSAGE_BODY_TYPE_TEXT, &err))
+ /* save the file */
+ if (do_save) {
+ if (!libbalsa_message_body_save_vfs(mime_body, save_file,
+ LIBBALSA_MESSAGE_BODY_UNSAFE,
+ mime_body->body_type ==
+ LIBBALSA_MESSAGE_BODY_TYPE_TEXT,
+ &err))
balsa_information(LIBBALSA_INFORMATION_ERROR,
_("Could not save %s: %s"),
- filename, err ? err->message : "Unknown error");
- g_free(filename);
+ file_uri, err ? err->message : "Unknown error");
+ }
+
+ g_object_unref(save_file);
+ g_free(file_uri);
}
static void
Modified: trunk/src/balsa-mime-widget-message.c
==============================================================================
--- trunk/src/balsa-mime-widget-message.c (original)
+++ trunk/src/balsa-mime-widget-message.c Fri Apr 25 18:19:30 2008
@@ -90,7 +90,6 @@
if (!g_ascii_strcasecmp("message/external-body", content_type)) {
gchar *access_type;
rfc_extbody_id *extbody_type = rfc_extbodys;
- BalsaMimeWidget *mw = NULL;
access_type =
libbalsa_message_body_get_parameter(mime_body, "access-type");
@@ -150,19 +149,14 @@
BalsaMimeWidget *mw;
if (url_type == RFC2046_EXTBODY_LOCALFILE) {
- gchar *local_name;
-
- local_name =
- libbalsa_message_body_get_parameter(mime_body, "name");
+ url = libbalsa_message_body_get_parameter(mime_body, "name");
- if (!local_name)
+ if (!url)
return NULL;
- url = g_strdup_printf("file:%s", local_name);
msg = g_string_new(_("Content Type: external-body\n"));
g_string_append_printf(msg, _("Access type: local-file\n"));
- g_string_append_printf(msg, _("File name: %s"), local_name);
- g_free(local_name);
+ g_string_append_printf(msg, _("File name: %s"), url);
} else if (url_type == RFC2017_EXTBODY_URL) {
gchar *local_name;
Modified: trunk/src/information-dialog.h
==============================================================================
--- trunk/src/information-dialog.h (original)
+++ trunk/src/information-dialog.h Fri Apr 25 18:19:30 2008
@@ -31,10 +31,20 @@
BALSA_INFORMATION_SHOW_STDERR,
};
-void balsa_information(LibBalsaInformationType type, const char *fmt, ...);
+void balsa_information(LibBalsaInformationType type, const char *fmt, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+;
+
void balsa_information_parented(GtkWindow *widget,
LibBalsaInformationType type,
- const char *fmt, ...);
+ const char *fmt, ...)
+#ifdef __GNUC__
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+;
+
void balsa_information_real(GtkWindow *parent, LibBalsaInformationType type,
const char *msg);
Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c (original)
+++ trunk/src/main.c Fri Apr 25 18:19:30 2008
@@ -284,7 +284,7 @@
{"compose", 'm', 0, G_OPTION_ARG_STRING, &(opt_compose_email),
N_("Compose a new email to EMAIL ADDRESS"), "EMAIL ADDRESS"},
{"attach", 'a', 0, G_OPTION_ARG_FILENAME_ARRAY, &(attach_vect),
- N_("Attach file at PATH"), "PATH"},
+ N_("Attach file at URI"), "URI"},
{"open-mailbox", 'o', 0, G_OPTION_ARG_STRING,
&(cmd_line_open_mailboxes),
N_("Opens MAILBOXNAME"), N_("MAILBOXNAME")},
@@ -859,7 +859,7 @@
for(lst = opt_attach_list; lst; lst = g_slist_next(lst))
add_attachment(snd, lst->data, FALSE, NULL);
snd->quit_on_close = FALSE;
- };
+ }
gtk_widget_show(window);
if (cmd_check_mail_on_startup || balsa_app.check_mail_upon_startup)
Modified: trunk/src/sendmsg-window.c
==============================================================================
--- trunk/src/sendmsg-window.c (original)
+++ trunk/src/sendmsg-window.c Fri Apr 25 18:19:30 2008
@@ -34,6 +34,7 @@
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
#include <glib/gi18n.h>
+#include <glib/gstdio.h>
#include <ctype.h>
#include <glib.h>
@@ -41,7 +42,6 @@
#include <locale.h>
#endif
-#include <sys/stat.h> /* for check_if_regular_file() */
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -114,7 +114,6 @@
static void close_window_cb (GtkAction * action, gpointer data);
-static gchar* check_if_regular_file(const gchar *);
static void balsa_sendmsg_destroy_handler(BalsaSendmsg * bsmsg);
static void check_readiness(BalsaSendmsg * bsmsg);
static void init_menus(BalsaSendmsg *);
@@ -667,7 +666,8 @@
BalsaSendmsg *bm; /* send message back reference */
GtkWidget *popup_menu; /* popup menu */
- gchar *filename; /* file name of the attachment */
+ LibbalsaVfs *file_uri; /* file uri of the attachment */
+ gchar *uri_ref; /* external body URI reference */
gchar *force_mime_type; /* force using this particular mime type */
gchar *charset; /* forced character set */
gboolean delete_on_destroy; /* destroy the file when not used any more */
@@ -735,7 +735,7 @@
BalsaAttachInfo * info = BALSA_ATTACH_INFO(object);
info->popup_menu = NULL;
- info->filename = NULL;
+ info->file_uri = NULL;
info->force_mime_type = NULL;
info->charset = NULL;
info->delete_on_destroy = FALSE;
@@ -763,24 +763,32 @@
info = BALSA_ATTACH_INFO(object);
/* unlink the file if necessary */
- if (info->delete_on_destroy) {
- char *last_slash = strrchr(info->filename, '/');
+ if (info->delete_on_destroy && info->file_uri) {
+ gchar * folder_name;
+ /* unlink the file */
if (balsa_app.debug)
fprintf (stderr, "%s:%s: unlink `%s'\n", __FILE__, __FUNCTION__,
- info->filename);
- unlink(info->filename);
- *last_slash = 0;
- if (balsa_app.debug)
- fprintf (stderr, "%s:%s: rmdir `%s'\n", __FILE__, __FUNCTION__,
- info->filename);
- rmdir(info->filename);
+ libbalsa_vfs_get_uri_utf8(info->file_uri));
+ libbalsa_vfs_file_unlink(info->file_uri, NULL);
+
+ /* remove the folder if possible */
+ folder_name = g_filename_from_uri(libbalsa_vfs_get_folder(info->file_uri),
+ NULL, NULL);
+ if (folder_name) {
+ if (balsa_app.debug)
+ fprintf (stderr, "%s:%s: rmdir `%s'\n", __FILE__, __FUNCTION__,
+ folder_name);
+ g_rmdir(folder_name);
+ g_free(folder_name);
+ }
}
/* clean up memory */
if (info->popup_menu)
gtk_widget_destroy(info->popup_menu);
- g_free(info->filename);
+ if (info->file_uri)
+ g_object_unref(G_OBJECT(info->file_uri));
g_free(info->force_mime_type);
g_free(info->charset);
libbalsa_message_headers_destroy(info->headers);
@@ -1702,14 +1710,9 @@
/* verify that the user *really* wants to attach as reference */
if (info->mode != new_mode && new_mode == LIBBALSA_ATTACH_AS_EXTBODY) {
GtkWidget *extbody_dialog, *parent;
- gchar *utf8name;
- GError *err = NULL;
gint result;
parent = gtk_widget_get_ancestor(menu_item, GNOME_TYPE_APP);
- utf8name = g_filename_to_utf8(info->filename, -1, NULL, NULL, &err);
- if (err)
- g_error_free(err);
extbody_dialog =
gtk_message_dialog_new(GTK_WINDOW(parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
@@ -1723,8 +1726,7 @@
"`real' file.\n\n"
"Do you really want to attach "
"this file as reference?"),
- utf8name);
- g_free(utf8name);
+ libbalsa_vfs_get_uri_utf8(info->file_uri));
gtk_window_set_title(GTK_WINDOW(extbody_dialog),
_("Attach as Reference?"));
result = gtk_dialog_run(GTK_DIALOG(extbody_dialog));
@@ -1763,7 +1765,7 @@
#endif /* HAVE_GNOME_VFS29 */
if (app) {
#if HAVE_GNOME_VFS29
- gchar *uri = g_strconcat("file://", info->filename, NULL);
+ gchar *uri = g_strdup(libbalsa_vfs_get_uri(info->file_uri));
GList *uris = g_list_prepend(NULL, uri);
gnome_vfs_mime_application_launch(app, uris);
g_free(uri);
@@ -1793,15 +1795,18 @@
on_open_url_cb(GtkWidget * menu_item, BalsaAttachInfo * info)
{
GError *err = NULL;
+ const gchar * uri;
g_return_if_fail(info != NULL);
+ uri = libbalsa_vfs_get_uri(info->file_uri);
+ g_return_if_fail(uri != NULL);
- g_message("open URL %s", info->filename + 4);
- // gnome_url_show(info->filename + 4, &err);
+ g_message("open URL %s", uri);
+ gnome_url_show(uri, &err);
if (err) {
balsa_information(LIBBALSA_INFORMATION_WARNING,
_("Error showing %s: %s\n"),
- info->filename + 4, err->message);
+ uri, err->message);
g_error_free(err);
}
}
@@ -1917,10 +1922,11 @@
charset = info->std;
if (info->win && (attr & LIBBALSA_TEXT_HI_CTRL)) {
charset = info->win;
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Character set for file %s changed "
- "from \"%s\" to \"%s\"."), filename,
- info->std, info->win);
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Character set for file %s changed "
+ "from \"%s\" to \"%s\"."), filename,
+ info->std, info->win);
}
}
*attach_charset = g_strdup(charset);
@@ -1981,38 +1987,46 @@
/* add_attachment:
- adds given filename to the list.
- takes over the ownership of filename.
+ adds given filename (uri format) to the list.
*/
gboolean
-add_attachment(BalsaSendmsg * bsmsg, gchar *filename,
+add_attachment(BalsaSendmsg * bsmsg, const gchar *filename,
gboolean is_a_temp_file, const gchar *forced_mime_type)
{
+ LibbalsaVfs * file_uri;
GtkTreeModel *model;
GtkTreeIter iter;
BalsaAttachInfo *attach_data;
gboolean can_inline, is_fwd_message;
gchar *content_type = NULL;
- gchar *err_bsmsg;
gchar *utf8name;
GError *err = NULL;
GdkPixbuf *pixbuf;
GtkWidget *menu_item;
- struct stat attach_stat;
if (balsa_app.debug)
fprintf(stderr, "Trying to attach '%s'\n", filename);
- if ( (err_bsmsg=check_if_regular_file(filename)) != NULL) {
- balsa_information(LIBBALSA_INFORMATION_ERROR, "%s", err_bsmsg);
- g_free(err_bsmsg);
- g_free(filename);
+ if (!(file_uri = libbalsa_vfs_new_from_uri(filename))) {
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_ERROR,
+ _("Cannot create file URI object for %s"),
+ filename);
+ return FALSE;
+ }
+ if (!libbalsa_vfs_is_regular_file(file_uri, &err)) {
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_ERROR,
+ "%s: %s", filename,
+ err && err->message ? err->message : _("unknown error"));
+ g_error_free(err);
+ g_object_unref(file_uri);
return FALSE;
}
#if defined(ENABLE_TOUCH_UI)
if(!bsmsg_check_format_compatibility(GTK_WINDOW(bsmsg->window),
filename)) {
- g_free(filename);
+ g_object_unref(file_uri);
return FALSE;
}
#endif /* ENABLE_TOUCH_UI */
@@ -2023,7 +2037,7 @@
if (is_fwd_message)
content_type = g_strdup(forced_mime_type);
pixbuf =
- libbalsa_icon_finder(forced_mime_type, filename, &content_type,
+ libbalsa_icon_finder(forced_mime_type, file_uri, &content_type,
GTK_ICON_SIZE_LARGE_TOOLBAR);
if (!content_type)
/* Last ditch. */
@@ -2038,7 +2052,6 @@
&change_type, &attach_data->charset)) {
g_free(content_type);
g_object_unref(attach_data);
- g_free(filename);
return FALSE;
}
if (change_type) {
@@ -2062,32 +2075,20 @@
g_free(tmp);
}
} else {
+ const gchar *uri_utf8 = libbalsa_vfs_get_uri_utf8(file_uri);
const gchar *home = g_getenv("HOME");
- if (home && !strncmp(filename, home, strlen(home))) {
- utf8name = g_filename_to_utf8(filename + strlen(home) - 1, -1,
- NULL, NULL, &err);
- if (utf8name)
- *utf8name = '~';
+ if (home && !strncmp(uri_utf8, "file://", 7) &&
+ !strncmp(uri_utf8 + 7, home, strlen(home))) {
+ utf8name = g_strdup_printf("~%s", uri_utf8 + 7 + strlen(home));
} else
- utf8name = g_filename_to_utf8(filename, -1, NULL, NULL, &err);
-
- if (err) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Error converting \"%s\" to UTF-8: %s\n"),
- filename, err->message);
- g_error_free(err);
- }
+ utf8name = g_strdup(uri_utf8);
}
- /* determine the size of the attachment */
- if (stat(filename, &attach_stat) == -1)
- attach_stat.st_size = 0;
-
model = BALSA_MSG_ATTACH_MODEL(bsmsg);
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
- attach_data->filename = filename;
+ attach_data->file_uri = file_uri;
attach_data->force_mime_type = g_strdup(forced_mime_type);
attach_data->delete_on_destroy = is_a_temp_file;
@@ -2166,7 +2167,7 @@
ATTACH_ICON_COLUMN, pixbuf,
ATTACH_TYPE_COLUMN, content_type,
ATTACH_MODE_COLUMN, attach_data->mode,
- ATTACH_SIZE_COLUMN, (gfloat) attach_stat.st_size,
+ ATTACH_SIZE_COLUMN, (gfloat) libbalsa_vfs_get_size(file_uri),
ATTACH_DESC_COLUMN, utf8name,
-1);
g_object_unref(attach_data);
@@ -2207,7 +2208,7 @@
model = BALSA_MSG_ATTACH_MODEL(bsmsg);
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
- attach_data->filename = g_strconcat("URL:", url, NULL);
+ attach_data->uri_ref = g_strconcat("URL:", url, NULL);
attach_data->force_mime_type = g_strdup("message/external-body");
attach_data->delete_on_destroy = FALSE;
attach_data->mode = LIBBALSA_ATTACH_AS_EXTBODY;
@@ -2241,7 +2242,7 @@
ATTACH_ICON_COLUMN, pixbuf,
ATTACH_TYPE_COLUMN, _("(URL)"),
ATTACH_MODE_COLUMN, attach_data->mode,
- ATTACH_SIZE_COLUMN, 0,
+ ATTACH_SIZE_COLUMN, (gfloat) 0.0,
ATTACH_DESC_COLUMN, url,
-1);
g_object_unref(attach_data);
@@ -2253,26 +2254,6 @@
return TRUE;
}
-static gchar*
-check_if_regular_file(const gchar * filename)
-{
- struct stat s;
- gchar *ptr = NULL;
-
- if (stat(filename, &s))
- ptr = g_strdup_printf(_("Cannot get info on file '%s': %s"),
- filename, strerror(errno));
- else if (!S_ISREG(s.st_mode))
- ptr =
- g_strdup_printf(
- _("Attachment %s is not a regular file."), filename);
- else if(access(filename, R_OK) != 0) {
- ptr =
- g_strdup_printf(_("File %s cannot be read\n"), filename);
- }
- return ptr;
-}
-
/* attach_dialog_ok:
processes the attachment file selection. Adds them to the list,
showing the attachment list, if was hidden.
@@ -2294,16 +2275,17 @@
}
fc = GTK_FILE_CHOOSER(dialog);
- files = gtk_file_chooser_get_filenames(fc);
- for (list = files; list; list = list->next)
+ files = gtk_file_chooser_get_uris(fc);
+ for (list = files; list; list = list->next) {
if(!add_attachment(bsmsg, list->data, FALSE, NULL))
res++;
+ g_free(list->data);
+ }
- /* add_attachment takes ownership of the filenames. */
g_slist_free(files);
g_free(balsa_app.attach_dir);
- balsa_app.attach_dir = gtk_file_chooser_get_current_folder(fc);
+ balsa_app.attach_dir = gtk_file_chooser_get_current_folder_uri(fc);
if (res == 0)
gtk_widget_destroy(dialog);
@@ -2321,12 +2303,14 @@
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+ gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fsw),
+ libbalsa_vfs_local_only());
gtk_window_set_destroy_with_parent(GTK_WINDOW(fsw), TRUE);
fc = GTK_FILE_CHOOSER(fsw);
gtk_file_chooser_set_select_multiple(fc, TRUE);
if (balsa_app.attach_dir)
- gtk_file_chooser_set_current_folder(fc, balsa_app.attach_dir);
+ gtk_file_chooser_set_current_folder_uri(fc, balsa_app.attach_dir);
g_signal_connect(G_OBJECT(fc), "response",
G_CALLBACK(attach_dialog_response), bsmsg);
@@ -2360,8 +2344,10 @@
g_free(name);
return FALSE;
}
- add_attachment(bsmsg, name,
- TRUE, "message/rfc822");
+ tmp_file_name = g_filename_to_uri(name, NULL, NULL);
+ g_free(name);
+ add_attachment(bsmsg, tmp_file_name, TRUE, "message/rfc822");
+ g_free(tmp_file_name);
return TRUE;
}
@@ -2408,9 +2394,10 @@
LibBalsaMessage *message = node->data;
if(!attach_message(bsmsg, message)) {
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Attaching message failed.\n"
- "Possible reason: not enough temporary space"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Attaching message failed.\n"
+ "Possible reason: not enough temporary space"));
break;
}
}
@@ -2442,14 +2429,11 @@
length = linebreak - uri_list;
- if (length && uri_list[0] != '#' && strncmp(uri_list,"file://",7)==0) {
+ if (length && uri_list[0] != '#') {
gchar *this_uri = g_strndup(uri_list, length);
- gchar *uri;
- uri = g_filename_from_uri(this_uri, NULL, NULL);
- g_free(this_uri);
- if (uri)
- list = g_slist_append(list, uri);
+ if (this_uri)
+ list = g_slist_append(list, this_uri);
}
uri_list = linebreak + 2;
@@ -2519,17 +2503,18 @@
continue;
if(!attach_message(bsmsg, message))
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Attaching message failed.\n"
- "Possible reason: not enough temporary space"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Attaching message failed.\n"
+ "Possible reason: not enough temporary space"));
g_object_unref(message);
}
balsa_index_selected_msgnos_free(index, selected);
} else if (info == TARGET_URI_LIST) {
GSList *uri_list = uri2gslist((gchar *) selection_data->data);
for (; uri_list; uri_list = g_slist_next(uri_list)) {
- add_attachment(bsmsg,
- uri_list->data, FALSE, NULL); /* steal strings */
+ add_attachment(bsmsg, uri_list->data, FALSE, NULL);
+ g_free(uri_list->data);
}
g_slist_free(uri_list);
} else if( info == TARGET_STRING) {
@@ -3054,11 +3039,13 @@
{
has_file_attached_t *find_file = (has_file_attached_t *)data;
BalsaAttachInfo *info;
+ const gchar * uri;
gtk_tree_model_get(model, iter, ATTACH_INFO_COLUMN, &info, -1);
if (!info)
return FALSE;
- if (!strcmp(find_file->name, info->filename))
+ uri = libbalsa_vfs_get_uri(info->file_uri);
+ if (uri && !strcmp(find_file->name, uri))
find_file->found = TRUE;
g_object_unref(info);
@@ -3119,9 +3106,9 @@
gtk_tree_model_foreach(BALSA_MSG_ATTACH_MODEL(bsmsg),
has_file_attached, &find_file);
if (!find_file.found)
- add_attachment(bsmsg, /* steal strings */
- uri_list->data, FALSE, NULL);
+ add_attachment(bsmsg, uri_list->data, FALSE, NULL);
}
+ g_slist_foreach(uri_list, (GFunc) g_free, NULL);
g_slist_free(uri_list);
}
break;
@@ -3300,9 +3287,9 @@
}
while (body) {
gchar *name, *body_type, *tmp_file_name;
- int fd;
GError *err = NULL;
- gboolean res;
+ gboolean res = FALSE;
+
if (body->filename) {
libbalsa_mktempdir(&tmp_file_name);
name = g_strdup_printf("%s/%s", tmp_file_name, body->filename);
@@ -3311,19 +3298,31 @@
LIBBALSA_MESSAGE_BODY_SAFE,
FALSE, &err);
} else {
- fd = g_file_open_tmp("balsa-continue-XXXXXX", &name, NULL);
- res = libbalsa_message_body_save_fd(body, fd, FALSE, &err);
+ int fd;
+
+ if ((fd = g_file_open_tmp("balsa-continue-XXXXXX", &name, NULL)) > 0) {
+ GMimeStream * tmp_stream;
+
+ if ((tmp_stream = g_mime_stream_fs_new(fd)) != NULL)
+ res = libbalsa_message_body_save_stream(body, tmp_stream, FALSE, &err);
+ else
+ close(fd);
+ }
}
if(!res) {
- balsa_information(LIBBALSA_INFORMATION_ERROR,
- _("Could not save attachment: %s"),
- err ? err->message : "Unknown error");
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_ERROR,
+ _("Could not save attachment: %s"),
+ err ? err->message : "Unknown error");
g_clear_error(&err);
/* FIXME: do not try any further? */
}
body_type = libbalsa_message_body_get_mime_type(body);
- add_attachment(bsmsg, name, TRUE, body_type);
+ tmp_file_name = g_filename_to_uri(name, NULL, NULL);
+ g_free(name);
+ add_attachment(bsmsg, tmp_file_name, TRUE, body_type);
g_free(body_type);
+ g_free(tmp_file_name);
body = body->next;
}
}
@@ -4936,9 +4935,10 @@
bsmsg->type = attach ? SEND_FORWARD_ATTACH : SEND_FORWARD_INLINE;
if (attach) {
if(!attach_message(bsmsg, message))
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Attaching message failed.\n"
- "Possible reason: not enough temporary space"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Attaching message failed.\n"
+ "Possible reason: not enough temporary space"));
bsmsg->state = SENDMSG_STATE_CLEAN;
set_entry_to_subject(GTK_ENTRY(bsmsg->subject[1]), message->body_list,
bsmsg->type, bsmsg->ident);
@@ -5100,28 +5100,32 @@
GtkFileChooser *attach;
if (!g_path_is_absolute(val)) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not attach the file %s: %s."), val,
- _("not an absolute path"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not attach the file %s: %s."), val,
+ _("not an absolute path"));
return;
}
if (!(g_str_has_prefix(val, g_get_home_dir())
|| g_str_has_prefix(val, g_get_tmp_dir()))) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not attach the file %s: %s."), val,
- _("not in your directory"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not attach the file %s: %s."), val,
+ _("not in your directory"));
return;
}
if (!g_file_test(val, G_FILE_TEST_EXISTS)) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not attach the file %s: %s."), val,
- _("does not exist"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not attach the file %s: %s."), val,
+ _("does not exist"));
return;
}
if (!g_file_test(val, G_FILE_TEST_IS_REGULAR)) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not attach the file %s: %s."), val,
- _("not a regular file"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not attach the file %s: %s."), val,
+ _("not a regular file"));
return;
}
attach = g_object_get_data(G_OBJECT(bsmsg->window),
@@ -5142,9 +5146,10 @@
g_free(valdir);
if (!good) {
/* gtk_file_chooser_select_filename will crash */
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not attach the file %s: %s."), val,
- _("not in current directory"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not attach the file %s: %s."), val,
+ _("not in current directory"));
return;
}
}
@@ -5273,8 +5278,9 @@
fname = gtk_file_chooser_get_filename(fc);
if ((fl = fopen(fname, "rt")) ==NULL) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not open the file %s.\n"), fname);
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not open the file %s.\n"), fname);
g_free(fname);
return;
}
@@ -5403,7 +5409,11 @@
/* create the attachment */
body = libbalsa_message_body_new(message);
- body->filename = g_strdup(attachment->filename);
+ body->file_uri = attachment->file_uri;
+ if (attachment->file_uri)
+ g_object_ref(attachment->file_uri);
+ else
+ body->filename = g_strdup(attachment->uri_ref);
body->content_type = g_strdup(attachment->force_mime_type);
body->charset = g_strdup(attachment->charset);
body->attach_mode = attachment->mode;
@@ -5432,8 +5442,8 @@
if (path && !(content =
libbalsa_get_header_from_path(header, path, NULL,
&err))) {
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- error_format, path, err->message);
+ balsa_information(LIBBALSA_INFORMATION_WARNING,
+ error_format, path, err->message);
g_error_free(err);
}
@@ -5846,9 +5856,10 @@
fcc = balsa_find_mailbox_by_url(bsmsg->fcc_url);
#ifdef HAVE_GPGME
- balsa_information(LIBBALSA_INFORMATION_DEBUG,
- _("sending message with gpg mode %d"),
- message->gpg_mode);
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_DEBUG,
+ _("sending message with gpg mode %d"),
+ message->gpg_mode);
#endif
#if ENABLE_ESMTP
@@ -5900,12 +5911,12 @@
}
if (error)
balsa_information_parented(GTK_WINDOW(bsmsg->window),
- LIBBALSA_INFORMATION_WARNING,
+ LIBBALSA_INFORMATION_ERROR,
_("Send failed: %s\n%s"), msg,
error->message);
else
balsa_information_parented(GTK_WINDOW(bsmsg->window),
- LIBBALSA_INFORMATION_WARNING,
+ LIBBALSA_INFORMATION_ERROR,
_("Send failed: %s"), msg);
return FALSE;
}
@@ -5943,6 +5954,7 @@
gboolean successp;
LibBalsaMessage *message;
GPtrArray *headers;
+ GError *error = NULL;
/* Silent fallback to UTF-8 */
message = bsmsg2message(bsmsg);
@@ -5978,21 +5990,24 @@
successp = libbalsa_message_postpone(message, balsa_app.draftbox,
bsmsg->parent_message,
(gchar **) headers->pdata,
- bsmsg->flow);
+ bsmsg->flow, &error);
else
successp = libbalsa_message_postpone(message, balsa_app.draftbox,
NULL,
(gchar **) headers->pdata,
- bsmsg->flow);
+ bsmsg->flow, &error);
g_ptr_array_foreach(headers, (GFunc) g_free, NULL);
g_ptr_array_free(headers, TRUE);
if(successp)
sw_delete_draft(bsmsg);
- else
+ else {
balsa_information_parented(GTK_WINDOW(bsmsg->window),
- LIBBALSA_INFORMATION_WARNING,
- _("Could not postpone message."));
+ LIBBALSA_INFORMATION_ERROR,
+ _("Could not postpone message: %s"),
+ error ? error->message : "");
+ g_clear_error(&error);
+ }
g_object_unref(G_OBJECT(message));
return successp;
@@ -6164,9 +6179,10 @@
bsmsg->spell_check_lang, &err);
if (!spell) {
/* Should not happen, since we now check the language. */
- libbalsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Error starting spell checker: %s"),
- err->message);
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Error starting spell checker: %s"),
+ err->message);
g_error_free(err);
/* No spell checker, so deactivate the button. */
@@ -6330,9 +6346,10 @@
return;
#else /* USE_GREGEX */
if (regcomp(&rex, balsa_app.quote_regex, REG_EXTENDED)) {
- balsa_information(LIBBALSA_INFORMATION_WARNING,
- _("Could not compile %s"),
- _("Quoted Text Regular Expression"));
+ balsa_information_parented(GTK_WINDOW(bsmsg->window),
+ LIBBALSA_INFORMATION_WARNING,
+ _("Could not compile %s"),
+ _("Quoted Text Regular Expression"));
return;
}
#endif /* USE_GREGEX */
Modified: trunk/src/sendmsg-window.h
==============================================================================
--- trunk/src/sendmsg-window.h (original)
+++ trunk/src/sendmsg-window.h Fri Apr 25 18:19:30 2008
@@ -128,7 +128,8 @@
void sendmsg_window_set_field(BalsaSendmsg *bsmsg, const gchar* key,
const gchar* val);
- gboolean add_attachment(BalsaSendmsg * bsmsg, char *filename,
+ gboolean add_attachment(BalsaSendmsg * bsmsg,
+ const gchar *filename,
gboolean is_a_tmp_file,
const gchar *forced_mime_type);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]