[Xfce4-commits] r24275 - in libexo/trunk: . exo-desktop-item-edit exo-mount exo-mount-notify po

Benedikt Meurer benny at xfce.org
Sat Jan 6 19:09:04 CET 2007


Author: benny
Date: 2007-01-06 18:09:04 +0000 (Sat, 06 Jan 2007)
New Revision: 24275

Added:
   libexo/trunk/exo-mount-notify/
   libexo/trunk/exo-mount-notify/Makefile.am
   libexo/trunk/exo-mount-notify/README
   libexo/trunk/exo-mount-notify/main.c
   libexo/trunk/exo-mount/
   libexo/trunk/exo-mount/Makefile.am
   libexo/trunk/exo-mount/README
   libexo/trunk/exo-mount/exo-mount-fstab.c
   libexo/trunk/exo-mount/exo-mount-fstab.h
   libexo/trunk/exo-mount/exo-mount-hal.c
   libexo/trunk/exo-mount/exo-mount-hal.h
   libexo/trunk/exo-mount/exo-mount-utils.c
   libexo/trunk/exo-mount/exo-mount-utils.h
   libexo/trunk/exo-mount/main.c
Modified:
   libexo/trunk/ChangeLog
   libexo/trunk/Makefile.am
   libexo/trunk/configure.in.in
   libexo/trunk/exo-desktop-item-edit/main.c
   libexo/trunk/po/ChangeLog
   libexo/trunk/po/POTFILES.in
   libexo/trunk/po/ca.po
   libexo/trunk/po/cs.po
   libexo/trunk/po/cy.po
   libexo/trunk/po/de.po
   libexo/trunk/po/dz.po
   libexo/trunk/po/el.po
   libexo/trunk/po/en_GB.po
   libexo/trunk/po/es.po
   libexo/trunk/po/et.po
   libexo/trunk/po/eu.po
   libexo/trunk/po/fi.po
   libexo/trunk/po/fr.po
   libexo/trunk/po/gl.po
   libexo/trunk/po/he.po
   libexo/trunk/po/hu.po
   libexo/trunk/po/it.po
   libexo/trunk/po/ja.po
   libexo/trunk/po/ka.po
   libexo/trunk/po/libexo-0.3.pot
   libexo/trunk/po/lt.po
   libexo/trunk/po/mk.po
   libexo/trunk/po/nl.po
   libexo/trunk/po/pa.po
   libexo/trunk/po/pl.po
   libexo/trunk/po/pt_BR.po
   libexo/trunk/po/ro.po
   libexo/trunk/po/ru.po
   libexo/trunk/po/sv.po
Log:
2007-01-06	Benedikt Meurer <benny at xfce.org>

	* configure.in.in, Makefile.am, exo-mount/: Add mount utility, that
	  uses HAL if available, but can also operate without HAL. This is
	  necessary because other mount utilities like gnome-mount or pmount
	  do not always work properly, esp. with devices such as floppy
	  drives. Even worse those utilities behave differently depending on
	  the underlying system, and thunar-vfs already contains too many
	  work arounds for such messy stuff.
	* configure.in.in, Makefile.am, exo-mount-notify/: Add an optional
	  internal mount notify, which notifies the user that a device is
	  being released by the system, and gives him a hint when the device
	  can be removed physically. This requires a running notification
	  daemon.
	* exo-desktop-item-edit/main.c(main): Update string to avoid
	  duplicated strings in the translations.
	* po/POTFILES.in: Add new files here.
	* po/libexo-0.3.pot, po/*.po: Merge new strings.
	* po/de.po: Update german translations.




Modified: libexo/trunk/ChangeLog
===================================================================
--- libexo/trunk/ChangeLog	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/ChangeLog	2007-01-06 18:09:04 UTC (rev 24275)
@@ -1,3 +1,23 @@
+2007-01-06	Benedikt Meurer <benny at xfce.org>
+
+	* configure.in.in, Makefile.am, exo-mount/: Add mount utility, that
+	  uses HAL if available, but can also operate without HAL. This is
+	  necessary because other mount utilities like gnome-mount or pmount
+	  do not always work properly, esp. with devices such as floppy
+	  drives. Even worse those utilities behave differently depending on
+	  the underlying system, and thunar-vfs already contains too many
+	  work arounds for such messy stuff.
+	* configure.in.in, Makefile.am, exo-mount-notify/: Add an optional
+	  internal mount notify, which notifies the user that a device is
+	  being released by the system, and gives him a hint when the device
+	  can be removed physically. This requires a running notification
+	  daemon.
+	* exo-desktop-item-edit/main.c(main): Update string to avoid
+	  duplicated strings in the translations.
+	* po/POTFILES.in: Add new files here.
+	* po/libexo-0.3.pot, po/*.po: Merge new strings.
+	* po/de.po: Update german translations.
+
 2007-01-03	Benedikt Meurer <benny at xfce.org>
 
 	* configure.in.in, exo-csource/main.c, exo-open/main.c,

Modified: libexo/trunk/Makefile.am
===================================================================
--- libexo/trunk/Makefile.am	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/Makefile.am	2007-01-06 18:09:04 UTC (rev 24275)
@@ -1,5 +1,9 @@
 # $Id$
 
+if HAVE_LIBNOTIFY
+EXO_MOUNT_NOTIFY_SUBDIR=exo-mount-notify
+endif
+
 if HAVE_PYTHON
 PYTHON_SUBDIR=python
 endif
@@ -10,6 +14,8 @@
 	exo-support							\
 	exo-desktop-item-edit						\
 	exo-helper							\
+	exo-mount							\
+	$(EXO_MOUNT_NOTIFY_SUBDIR)					\
 	exo-open							\
 	docs								\
 	icons								\

Modified: libexo/trunk/configure.in.in
===================================================================
--- libexo/trunk/configure.in.in	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/configure.in.in	2007-01-06 18:09:04 UTC (rev 24275)
@@ -104,16 +104,18 @@
 dnl *** Check for standard header files ***
 dnl ***************************************
 AC_HEADER_STDC()
-AC_CHECK_HEADERS([assert.h errno.h fcntl.h fnmatch.h libintl.h locale.h math.h \
-                  md5.h md5global.h mmintrin.h regex.h stdarg.h string.h sys/mman.h \
-                  sys/resource.h sys/stat.h sys/time.h sys/types.h sys/wait.h \
-                  time.h])
+AC_CHECK_HEADERS([assert.h errno.h fcntl.h fnmatch.h fstab.h libintl.h \
+                  locale.h math.h md5.h md5global.h mmintrin.h mntent.h \
+                  paths.h regex.h signal.h stdarg.h string.h sys/mman.h \
+                  sys/mnttab.h sys/mount.h sys/param.h sys/resource.h \
+                  sys/stat.h sys/time.h sys/types.h sys/ucred.h \
+                  sys/wait.h time.h])
 
 dnl ************************************
 dnl *** Check for standard functions ***
 dnl ************************************
 AC_FUNC_MMAP()
-AC_CHECK_FUNCS([regexec])
+AC_CHECK_FUNCS([getfsspec getfsstat getmntent regexec setmntent])
 
 dnl ******************************************
 dnl *** Check for Message Digest functions ***
@@ -140,6 +142,16 @@
 XDT_CHECK_OPTIONAL_PACKAGE([XFCE_MCS_MANAGER], [xfce-mcs-manager], [4.2.2],
                            [mcs-plugin], [xfce-mcs-manager], [yes])
 
+dnl **************************************
+dnl *** Check for libnotify (optional) ***
+dnl **************************************
+XDT_CHECK_OPTIONAL_PACKAGE([LIBNOTIFY], [libnotify], [0.4.0], [notifications], [Notifications support], [yes])
+
+dnl ********************************
+dnl *** Check for HAL (optional) ***
+dnl ********************************
+XDT_CHECK_OPTIONAL_PACKAGE([HAL], [hal-storage], [0.5.0], [hal], [HAL support], [yes])
+
 dnl *************************
 dnl *** Check for gtk-doc ***
 dnl *************************
@@ -355,6 +367,8 @@
 exo-desktop-item-edit/Makefile
 exo-helper/Makefile
 exo-helper/helpers/Makefile
+exo-mount/Makefile
+exo-mount-notify/Makefile
 exo-open/Makefile
 exo-support/Makefile
 icons/Makefile
@@ -368,3 +382,18 @@
 tests/Makefile
 tests/data/Makefile
 ])
+
+dnl ***************************
+dnl *** Print configuration ***
+dnl ***************************
+echo
+echo "Build Configuration:"
+echo
+if test x"$HAL_FOUND" = x"yes"; then
+echo "* HAL support:    yes"
+else
+echo "* HAL support:    no"
+fi
+echo "* Debug Support:  $enable_debug"
+echo "* Python Support: $have_python"
+echo

Modified: libexo/trunk/exo-desktop-item-edit/main.c
===================================================================
--- libexo/trunk/exo-desktop-item-edit/main.c	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/exo-desktop-item-edit/main.c	2007-01-06 18:09:04 UTC (rev 24275)
@@ -135,7 +135,7 @@
         {
           /* no error message, the GUI initialization failed */
           const gchar *display_name = gdk_get_display_arg_name ();
-          s = g_strdup_printf (_("Failed to open display: %s"), (display_name != NULL) ? display_name : " ");
+          s = g_strdup_printf ("%s: %s", _("Failed to open display"), (display_name != NULL) ? display_name : " ");
         }
 
       /* tell the user about it */


Property changes on: libexo/trunk/exo-mount
___________________________________________________________________
Name: svn:ignore
   + .deps
.libs
Makefile
Makefile.in
exo-mount
.*.swp


Copied: libexo/trunk/exo-mount/Makefile.am (from rev 24254, libexo/trunk/exo-open/Makefile.am)
===================================================================
--- libexo/trunk/exo-mount/Makefile.am	                        (rev 0)
+++ libexo/trunk/exo-mount/Makefile.am	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,54 @@
+# $Id$
+
+INCLUDES = 								\
+	-I$(top_srcdir)							\
+	-DDBUS_API_SUBJECT_TO_CHANGE					\
+	-DEXO_API_SUBJECT_TO_CHANGE					\
+	-DG_LOG_DOMAIN=\"exo-mount\"					\
+	-DLIBEXECDIR=\"$(libexecdir)\"					\
+	-DLIBEXO_VERSION_API=\"$(LIBEXO_VERSION_API)\"			\
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"
+
+bin_PROGRAMS =								\
+	exo-mount
+
+exo_mount_SOURCES =							\
+	exo-mount-fstab.c						\
+	exo-mount-fstab.h						\
+	exo-mount-utils.c						\
+	exo-mount-utils.h						\
+	main.c
+
+if HAVE_HAL
+exo_mount_SOURCES +=							\
+	exo-mount-hal.c							\
+	exo-mount-hal.h
+endif
+
+exo_mount_CFLAGS =							\
+	$(GTK_CFLAGS)							\
+	$(HAL_CFLAGS)							\
+	$(LIBXFCE4UTIL_CFLAGS)
+
+exo_mount_LDFLAGS =							\
+	-no-undefined
+
+exo_mount_DEPENDENCIES =						\
+	$(top_builddir)/exo/libexo-$(LIBEXO_VERSION_MAJOR).$(LIBEXO_VERSION_MINOR).la
+
+exo_mount_LDADD =							\
+	$(GTK_LIBS)							\
+	$(HAL_LIBS)							\
+	$(LIBXFCE4UTIL_LIBS)						\
+	$(top_builddir)/exo/libexo-$(LIBEXO_VERSION_MAJOR).$(LIBEXO_VERSION_MINOR).la
+
+# install apppropriate symlinks
+install-data-local:
+	$(mkinstalldirs) $(DESTDIR)$(bindir)
+	-( cd $(DESTDIR)$(bindir) ; ln -sf exo-mount exo-eject )
+	-( cd $(DESTDIR)$(bindir) ; ln -sf exo-mount exo-unmount )
+
+EXTRA_DIST =								\
+	README
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

Added: libexo/trunk/exo-mount/README
===================================================================
--- libexo/trunk/exo-mount/README	                        (rev 0)
+++ libexo/trunk/exo-mount/README	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,11 @@
+What is this?
+=============
+
+exo-mount is a volume mounter, which is used to mount, eject or unmount volumes
+based on their HAL UDIs or their device files. The HAL support is optional, but
+highly recommended. See the output of
+
+	exo-mount --help
+
+for available command line options.
+

Added: libexo/trunk/exo-mount/exo-mount-fstab.c
===================================================================
--- libexo/trunk/exo-mount/exo-mount-fstab.c	                        (rev 0)
+++ libexo/trunk/exo-mount/exo-mount-fstab.c	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,405 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#endif
+
+#ifdef HAVE_FSTAB_H
+#include <fstab.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <exo-mount/exo-mount-fstab.h>
+#include <exo-mount/exo-mount-utils.h>
+
+
+
+/* define _PATH_FSTAB if undefined */
+#ifndef _PATH_FSTAB
+#ifdef sun
+#define _PATH_FSTAB "/etc/vfstab"
+#else
+#define _PATH_FSTAB "/etc/fstab"
+#endif
+#endif
+
+/* define _PATH_MOUNT if undefined */
+#ifndef _PATH_MOUNT
+#define _PATH_MOUNT "/bin/mount"
+#endif
+
+
+
+static gboolean exo_mount_fstab_exec   (const gchar *command,
+                                        const gchar *argument,
+                                        GError     **error);
+static gchar   *exo_mount_fstab_lookup (const gchar *device_file,
+                                        GError     **error) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+
+
+static gboolean
+exo_mount_fstab_exec (const gchar *command,
+                      const gchar *argument,
+                      GError     **error)
+{
+  gboolean result;
+  gchar   *standard_error;
+  gchar   *command_line;
+  gchar   *quoted;
+  gint     status;
+
+  g_return_val_if_fail (command != NULL, FALSE);
+  g_return_val_if_fail (argument != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* generate the command line */
+  quoted = g_shell_quote (argument);
+  command_line = g_strconcat (command, " ", quoted, NULL);
+  g_free (quoted);
+
+  /* try to execute the command line */
+  result = g_spawn_command_line_sync (command_line, NULL, &standard_error, &status, error);
+  if (G_LIKELY (result))
+    {
+      /* check if the command failed */
+      if (G_UNLIKELY (status != 0))
+        {
+          /* drop additional whitespace from the stderr output */
+          g_strstrip (standard_error);
+
+          /* strip all trailing dots from the stderr output */
+          while (*standard_error != '\0' && standard_error[strlen (standard_error) - 1] == '.')
+            standard_error[strlen (standard_error) - 1] = '\0';
+
+          /* generate an error from the stderr output */
+          if (G_LIKELY (*standard_error != '\0'))
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", standard_error);
+          else
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unknown error"));
+
+          /* and yes, we failed */
+          result = FALSE;
+        }
+
+      /* release the stderr output */
+      g_free (standard_error);
+    }
+
+  /* cleanup */
+  g_free (command_line);
+
+  return result;
+}
+
+
+
+static gchar*
+exo_mount_fstab_lookup (const gchar *device_file,
+                        GError     **error)
+{
+  gchar *path = NULL;
+
+#if defined(HAVE_SETMNTENT) /* Linux */
+  struct mntent *mntent;
+  gchar         *resolved;
+  FILE          *fp;
+
+  /* try to open the fstab file */
+  fp = setmntent (_PATH_FSTAB, "r");
+  if (G_UNLIKELY (fp == NULL))
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("Failed to open file \"%s\": %s"), _PATH_FSTAB,
+                   g_strerror (errno));
+      return NULL;
+    }
+
+  /* look up an entry for our device file */
+  while (path == NULL)
+    {
+      /* grab the next entry */
+      mntent = getmntent (fp);
+      if (mntent == NULL)
+        break;
+
+      /* check if this entry matches */
+      if (strcmp (device_file, mntent->mnt_fsname) == 0)
+        {
+          /* exakt match, nice */
+          path = g_strdup (mntent->mnt_dir);
+        }
+      else
+        {
+          /* but maybe the fstab entry is a symlink */
+          resolved = exo_mount_utils_resolve (mntent->mnt_fsname);
+          if (strcmp (device_file, resolved) == 0)
+            path = g_strdup (mntent->mnt_dir);
+          g_free (resolved);
+        }
+    }
+
+  /* close the file handle */
+  endmntent (fp);
+#elif defined(HAVE_GETMNTENT) /* Solaris */
+  struct mnttab mntent;
+  gchar        *resolved;
+  FILE         *fp;
+
+  /* try to open the fstab file */
+  fp = fopen (_PATH_FSTAB, "r");
+  if (G_UNLIKELY (fp == NULL))
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("Failed to open file \"%s\": %s"), _PATH_FSTAB,
+                   g_strerror (errno));
+      return NULL;
+    }
+
+  /* look up an entry for our device file */
+  while (path == NULL)
+    {
+      /* grab the next entry */
+      if (getmntent (fp, &mntent) != 0)
+        break;
+
+      /* check if this entry matches */
+      if (strcmp (device_file, mntent.mnt_special) == 0)
+        {
+          /* exakt match, nice */
+          path = g_strdup (mntent.mnt_mountp);
+        }
+      else
+        {
+          /* but maybe the fstab entry is a symlink */
+          resolved = exo_mount_utils_resolve (mntent.mnt_special);
+          if (strcmp (device_file, resolved) == 0)
+            path = g_strdup (mntent.mnt_mountp);
+          g_free (resolved);
+        }
+    }
+
+  /* close the file handle */
+  fclose (fp);
+#elif defined(HAVE_GETFSSPEC) /* FreeBSD */
+  struct fstab *fs;
+
+  /* look up the entry for the device file,
+   * fortunately FreeBSD isn't playing the
+   * weird symlink tricks for most devices,
+   * so we don't need the damn stupid Linux
+   * symlink resolving stuff here...
+   */
+  fs = getfsspec (device_file);
+  if (G_LIKELY (fs != NULL))
+    {
+      /* check if this is a usable file system */
+      if (strcmp (fs->fs_type, FSTAB_SW) != 0
+#ifdef FSTAB_DP
+          && strcmp (fs->fs_type, FSTAB_DP) != 0
+#endif
+          && strcmp (fs->fs_type, FSTAB_XX) != 0)
+        {
+          /* jap, usable file system */
+          path = g_strdup (fs->fs_file);
+        }
+    }
+#else
+#error "Add support for your operating system here."
+#endif
+
+  /* check if we failed to find the entry */
+  if (G_UNLIKELY (path == NULL))
+    {
+      /* generate an appropriate error message */
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Device \"%s\" not found in file system device table"), device_file);
+    }
+
+  return path;
+}
+
+
+
+/**
+ * exo_mount_fstab_contains:
+ * @device_file : the absolute path to a block device file.
+ *
+ * Checks whether an entry for the @device_file exists in the
+ * file system table file <tt>/etc/fstab</tt>. Returns %TRUE if
+ * such an entry exists, %FALSE otherwise.
+ *
+ * Return value: %TRUE if an entry for @device_file is present
+ *               in <tt>/dev/fstab</tt>, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_fstab_contains (const gchar *device_file)
+{
+  gchar *mount_point;
+
+  g_return_val_if_fail (g_path_is_absolute (device_file), FALSE);
+
+  /* check if we have an fstab entry */
+  mount_point = exo_mount_fstab_lookup (device_file, NULL);
+  if (G_LIKELY (mount_point != NULL))
+    {
+      /* jap, match found */
+      g_free (mount_point);
+      return TRUE;
+    }
+
+  /* no match */
+  return FALSE;
+}
+
+
+
+/**
+ * exo_mount_fstab_eject:
+ * @device_file : the absolute path to a block device file.
+ * @error       : return location for errors or %NULL.
+ *
+ * Ejects the device identified by the @device_file. Returns
+ * %TRUE if the device was successfully ejected, %FALSE otherwise.
+ *
+ * Return value: %TRUE on success, %FALSE if @error is set.
+ **/
+gboolean
+exo_mount_fstab_eject (const gchar *device_file,
+                       GError     **error)
+{
+  gboolean result;
+  gchar   *mount_point;
+  gchar   *device_name;
+
+  g_return_val_if_fail (g_path_is_absolute (device_file), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* verify that the device is listed in the fstab */
+  mount_point = exo_mount_fstab_lookup (device_file, error);
+  if (G_UNLIKELY (mount_point == NULL))
+    return FALSE;
+  g_free (mount_point);
+
+  /* try to eject the device */
+  device_name = g_path_get_basename (device_file);
+  result = exo_mount_fstab_exec ("eject", device_name, error);
+  g_free (device_name);
+
+  return result;
+}
+
+
+
+/**
+ * exo_mount_fstab_mount:
+ * @device_file : the absolute path to a block device file.
+ * @error       : return location for errors or %NULL.
+ *
+ * Mounts the device identified by the @device_file. Returns %TRUE
+ * if the device was successfully mounted, %FALSE in case or an
+ * error.
+ *
+ * Return value: %TRUE if successfull, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_fstab_mount (const gchar *device_file,
+                       GError     **error)
+{
+  gboolean result;
+  gchar   *mount_point;
+
+  g_return_val_if_fail (g_path_is_absolute (device_file), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* determine the mount point of the device from the fstab */
+  mount_point = exo_mount_fstab_lookup (device_file, error);
+  if (G_UNLIKELY (mount_point == NULL))
+    return FALSE;
+
+  /* try to mount the device */
+  result = exo_mount_fstab_exec (_PATH_MOUNT, mount_point, error);
+
+  /* cleanup */
+  g_free (mount_point);
+
+  return result;
+}
+
+
+
+
+/**
+ * exo_mount_fstab_unmount:
+ * @device_file : the absolute path to a block device file.
+ * @error       : return location for errors or %NULL.
+ *
+ * Unmounts the device identified by the @device_file. Returns
+ * %TRUE if the device was successfully unmounted, %FALSE in
+ * case of an error.
+ *
+ * Return value: %TRUE if successfull, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_fstab_unmount (const gchar *device_file,
+                         GError     **error)
+{
+  gboolean result;
+  gchar   *mount_point;
+  gchar   *dirname;
+  gchar   *command;
+
+  g_return_val_if_fail (g_path_is_absolute (device_file), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* determine the mount point of the device from the fstab */
+  mount_point = exo_mount_fstab_lookup (device_file, error);
+  if (G_UNLIKELY (mount_point == NULL))
+    return FALSE;
+
+  /* determine umount from _PATH_MOUNT */
+  dirname = g_path_get_dirname (_PATH_MOUNT);
+  command = g_build_filename (dirname, "umount", NULL);
+  g_free (dirname);
+
+  /* try to mount the device */
+  result = exo_mount_fstab_exec (command, mount_point, error);
+
+  /* cleanup */
+  g_free (mount_point);
+  g_free (command);
+
+  return result;
+}


Property changes on: libexo/trunk/exo-mount/exo-mount-fstab.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Added: libexo/trunk/exo-mount/exo-mount-fstab.h
===================================================================
--- libexo/trunk/exo-mount/exo-mount-fstab.h	                        (rev 0)
+++ libexo/trunk/exo-mount/exo-mount-fstab.h	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,40 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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 __EXO_MOUNT_FSTAB_H__
+#define __EXO_MOUNT_FSTAB_H__
+
+#include <exo/exo.h>
+
+G_BEGIN_DECLS;
+
+gboolean exo_mount_fstab_contains (const gchar *device_file) G_GNUC_INTERNAL;
+
+gboolean exo_mount_fstab_eject    (const gchar *device_file,
+                                   GError     **error) G_GNUC_INTERNAL;
+
+gboolean exo_mount_fstab_mount    (const gchar *device_file,
+                                   GError     **error) G_GNUC_INTERNAL;
+
+gboolean exo_mount_fstab_unmount  (const gchar *device_file,
+                                   GError     **error) G_GNUC_INTERNAL;
+
+G_END_DECLS;
+
+#endif /* !__EXO_MOUNT_FSTAB_H__ */


Property changes on: libexo/trunk/exo-mount/exo-mount-fstab.h
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Added: libexo/trunk/exo-mount/exo-mount-hal.c
===================================================================
--- libexo/trunk/exo-mount/exo-mount-hal.c	                        (rev 0)
+++ libexo/trunk/exo-mount/exo-mount-hal.c	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,966 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <libhal.h>
+#include <libhal-storage.h>
+
+#include <exo-mount/exo-mount-hal.h>
+
+
+
+static gboolean exo_mount_hal_init            (GError   **error);
+static void     exo_mount_hal_propagate_error (GError   **error,
+                                               DBusError *derror);
+
+
+
+struct _ExoMountHalDevice
+{
+  gchar            *udi;
+  LibHalDrive      *drive;
+  LibHalVolume     *volume;
+
+  /* device internals */
+  const gchar      *file;
+  const gchar      *name;
+
+  /* file system options */
+  gchar           **fsoptions;
+  const gchar      *fstype;
+  LibHalVolumeUsage fsusage;
+};
+
+
+
+static LibHalContext  *hal_context = NULL;
+static DBusConnection *dbus_connection = NULL;
+
+
+
+static gboolean
+exo_mount_hal_init (GError **error)
+{
+  DBusError derror;
+
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* check if HAL support is already initialized */
+  if (G_LIKELY (hal_context == NULL))
+    {
+      /* initialize D-Bus error */
+      dbus_error_init (&derror);
+
+      /* try to connect to the system bus */
+      dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror);
+      if (G_LIKELY (dbus_connection != NULL))
+        {
+          /* try to allocate a new HAL context */
+          hal_context = libhal_ctx_new ();
+          if (G_LIKELY (hal_context != NULL))
+            {
+              /* setup the D-Bus connection for the HAL context */
+              libhal_ctx_set_dbus_connection (hal_context, dbus_connection);
+
+              /* try to initialize the HAL context */
+              libhal_ctx_init (hal_context, &derror);
+            }
+          else
+            {
+              /* record the allocation failure of the context */
+              dbus_set_error_const (&derror, DBUS_ERROR_NO_MEMORY, g_strerror (ENOMEM));
+            }
+        }
+
+      /* check if we failed */
+      if (dbus_error_is_set (&derror))
+        {
+          /* check if a HAL context was allocated */
+          if (G_UNLIKELY (hal_context != NULL))
+            {
+              /* drop the allocated HAL context */
+              libhal_ctx_shutdown (hal_context, NULL);
+              libhal_ctx_free (hal_context);
+              hal_context = NULL;
+            }
+
+          /* propagate the error */
+          exo_mount_hal_propagate_error (error, &derror);
+        }
+    }
+
+  return (hal_context != NULL);
+}
+
+
+
+static void
+exo_mount_hal_propagate_error (GError   **error,
+                               DBusError *derror)
+{
+  g_return_if_fail (error == NULL || *error == NULL);
+
+  /* check if we need to propragate an error */
+  if (G_LIKELY (derror != NULL && dbus_error_is_set (derror)))
+    {
+      /* propagate the error */
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s", derror->message);
+
+      /* reset the D-Bus error */
+      dbus_error_free (derror);
+    }
+}
+
+
+
+/**
+ * exo_mount_hal_device_from_udi:
+ * @udi   : UDI of a volume or drive.
+ * @error : return location for errors or %NULL.
+ *
+ * The returned object must be freed when no longer
+ * needed using exo_mount_hal_device_free().
+ *
+ * Return value: the #ExoMountHalDevice for the @udi
+ *               or %NULL in case of an error.
+ **/
+ExoMountHalDevice*
+exo_mount_hal_device_from_udi (const gchar *udi,
+                               GError     **error)
+{
+  ExoMountHalDevice *device = NULL;
+  DBusError          derror;
+  gchar            **interfaces;
+  gint               n;
+
+  g_return_val_if_fail (udi != NULL, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  /* make sure the HAL support is initialized */
+  if (!exo_mount_hal_init (error))
+    return NULL;
+
+  /* initialize D-Bus error */
+  dbus_error_init (&derror);
+
+  /* determine the info.interfaces property of the device */
+  interfaces = libhal_device_get_property_strlist (hal_context, udi, "info.interfaces", &derror);
+  if (G_UNLIKELY (interfaces == NULL))
+    {
+err0: exo_mount_hal_propagate_error (error, &derror);
+      goto out;
+    }
+
+  /* verify that we have a mountable device here */
+  for (n = 0; interfaces[n] != NULL; ++n)
+    if (strcmp (interfaces[n], "org.freedesktop.Hal.Device.Volume") == 0)
+      break;
+  if (G_UNLIKELY (interfaces[n] == NULL))
+    {
+      /* definitely not a device that we're able to mount, eject or unmount */
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Given device \"%s\" is not a volume or drive"), udi);
+      goto out;
+    }
+
+  /* setup the device struct */
+  device = g_new0 (ExoMountHalDevice, 1);
+  device->udi = g_strdup (udi);
+
+  /* check if we have a volume here */
+  device->volume = libhal_volume_from_udi (hal_context, udi);
+  if (G_LIKELY (device->volume != NULL))
+    {
+      /* determine the storage drive for the volume */
+      device->drive = libhal_drive_from_udi (hal_context, libhal_volume_get_storage_device_udi (device->volume));
+      if (G_LIKELY (device->drive != NULL))
+        {
+          /* setup the device internals */
+          device->file = libhal_volume_get_device_file (device->volume);
+          device->name = libhal_volume_get_label (device->volume);
+
+          /* setup the file system internals */
+          device->fstype = libhal_volume_get_fstype (device->volume);
+          device->fsusage = libhal_volume_get_fsusage (device->volume);
+        }
+    }
+  else
+    {
+      /* check if we have a drive here (i.e. floppy) */
+      device->drive = libhal_drive_from_udi (hal_context, udi);
+      if (G_LIKELY (device->drive != NULL))
+        {
+          /* setup the device internals */
+          device->file = libhal_drive_get_device_file (device->drive);
+          device->name = libhal_drive_get_model (device->drive);
+
+          /* setup the file system internals */
+          device->fstype = "";
+          device->fsusage = LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM;
+        }
+    }
+
+  /* determine the valid mount options from the UDI */
+  device->fsoptions = libhal_device_get_property_strlist (hal_context, udi, "volume.mount.valid_options", &derror);
+  if (G_UNLIKELY (device->file == NULL || device->name == NULL || device->fsoptions == NULL))
+    {
+      exo_mount_hal_device_free (device);
+      goto err0;
+    }
+
+  /* check if we failed */
+  if (G_LIKELY (device->drive == NULL))
+    {
+      /* definitely not a device that we're able to mount, eject or unmount */
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Given device \"%s\" is not a volume or drive"), udi);
+      exo_mount_hal_device_free (device);
+      device = NULL;
+    }
+
+out:
+  /* cleanup */
+  libhal_free_string_array (interfaces);
+
+  return device;
+}
+
+
+
+/**
+ * exo_mount_hal_device_from_file:
+ * @file  : absolute path to a device file.
+ * @error : return location for errors or %NULL.
+ *
+ * The returned object must be freed using
+ * exo_mount_hal_device_free() when no longer
+ * needed.
+ *
+ * Return value: the #ExoMountHalDevice for the device
+ *               @file, or %NULL in case of an error.
+ **/
+ExoMountHalDevice*
+exo_mount_hal_device_from_file (const gchar *file,
+                                GError     **error)
+{
+  ExoMountHalDevice *device = NULL;
+  DBusError          derror;
+  gchar            **interfaces;
+  gchar            **udis;
+  gint               n_udis;
+  gint               n, m;
+
+  g_return_val_if_fail (g_path_is_absolute (file), NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  /* make sure the HAL support is initialized */
+  if (!exo_mount_hal_init (error))
+    return NULL;
+
+  /* initialize D-Bus error */
+  dbus_error_init (&derror);
+
+  /* query matching UDIs from HAL */
+  udis = libhal_manager_find_device_string_match (hal_context, "block.device", file, &n_udis, &derror);
+  if (G_UNLIKELY (udis == NULL))
+    {
+      /* propagate the error */
+      exo_mount_hal_propagate_error (error, &derror);
+      return NULL;
+    }
+
+  /* look for an UDI that specifies the Volume interface */
+  for (n = 0; n < n_udis; ++n)
+    {
+      /* check if we should ignore this device */
+      if (libhal_device_get_property_bool (hal_context, udis[n], "info.ignore", NULL))
+        continue;
+
+      /* determine the info.interfaces property of the device */
+      interfaces = libhal_device_get_property_strlist (hal_context, udis[n], "info.interfaces", NULL);
+      if (G_UNLIKELY (interfaces == NULL))
+        continue;
+
+      /* check if we have a mountable device here */
+      for (m = 0; interfaces[m] != NULL; ++m)
+        if (strcmp (interfaces[m], "org.freedesktop.Hal.Device.Volume") == 0)
+          break;
+
+      /* check if it's a usable device */
+      if (interfaces[m] != NULL)
+        {
+          libhal_free_string_array (interfaces);
+          break;
+        }
+
+      /* next one, please */
+      libhal_free_string_array (interfaces);
+    }
+
+  /* check if we have an UDI */
+  if (G_LIKELY (n < n_udis))
+    {
+      /* try to query the device from the HAL daemon */
+      device = exo_mount_hal_device_from_udi (udis[n], error);
+    }
+  else
+    {
+      /* tell the caller that no matching device was found */
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL, _("Device \"%s\" not found in file system device table"), file);
+    }
+
+  /* cleanup */
+  libhal_free_string_array (udis);
+
+  return device;
+}
+
+
+
+/**
+ * exo_mount_hal_device_free:
+ * @device : an #ExoMountHalDevice or %NULL.
+ *
+ * Releases the resources allocated to the @device.
+ **/
+void
+exo_mount_hal_device_free (ExoMountHalDevice *device)
+{
+  /* check if we have a device */
+  if (G_LIKELY (device != NULL))
+    {
+      libhal_free_string_array (device->fsoptions);
+      libhal_volume_free (device->volume);
+      libhal_drive_free (device->drive);
+      g_free (device->udi);
+      g_free (device);
+    }
+}
+
+
+
+/**
+ * exo_mount_hal_device_get_file:
+ * @device : an #ExoMountHalDevice.
+ *
+ * Returns the path of the @device file. The caller
+ * is responsible to free the returned string using
+ * g_free() when no longer needed.
+ *
+ * Return value: the @device file path.
+ **/
+gchar*
+exo_mount_hal_device_get_file (ExoMountHalDevice *device)
+{
+  g_return_val_if_fail (device != NULL, NULL);
+  return g_strdup (device->file);
+}
+
+
+
+/**
+ * exo_mount_hal_device_get_name:
+ * @device : an #ExoMountHalDevice.
+ *
+ * Returns the visible name of the @device. The caller
+ * is responsible to free the returned string using
+ * g_free() when no longer needed.
+ *
+ * Return value: the @device<!---->s visible name.
+ **/
+gchar*
+exo_mount_hal_device_get_name (ExoMountHalDevice *device)
+{
+  g_return_val_if_fail (device != NULL, NULL);
+  return g_strdup (device->name);
+}
+
+
+
+/**
+ * exo_mount_hal_device_get_icon:
+ * @device : an #ExoMountHalDevice.
+ *
+ * Returns the icon name for the @device or %NULL if no
+ * icon could be determined. The caller is responsible
+ * to free the returned string icon using g_free() when
+ * no longer needed.
+ *
+ * Return value: the icon name for @device or %NULL.
+ **/
+gchar*
+exo_mount_hal_device_get_icon (ExoMountHalDevice *device)
+{
+  GtkIconTheme *icon_theme;
+
+  g_return_val_if_fail (device != NULL, NULL);
+
+  /* determine the default icon theme */
+  icon_theme = gtk_icon_theme_get_default ();
+
+  /* determine the icon from the type (keep in sync
+   * with thunar-vfs to get consistent icons).
+   */
+  switch (libhal_drive_get_type (device->drive))
+    {
+    case LIBHAL_DRIVE_TYPE_CDROM:
+      /* check which of CD-ROM/DVD we have */
+      switch (libhal_volume_get_disc_type (device->volume))
+        {
+cdrom:  case LIBHAL_VOLUME_DISC_TYPE_CDROM:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-cdrom"))
+            return g_strdup ("gnome-dev-cdrom");
+          break;
+
+        case LIBHAL_VOLUME_DISC_TYPE_CDR:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-cdr"))
+            return g_strdup ("gnome-dev-disc-cdr");
+          goto cdrom;
+
+        case LIBHAL_VOLUME_DISC_TYPE_CDRW:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-cdrw"))
+            return g_strdup ("gnome-dev-disc-cdrw");
+          goto cdrom;
+
+dvdrom: case LIBHAL_VOLUME_DISC_TYPE_DVDROM:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdrom"))
+            return g_strdup ("gnome-dev-disc-dvdrom");
+          else if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-dvd"))
+            return g_strdup ("gnome-dev-dvd");
+          goto cdrom;
+
+        case LIBHAL_VOLUME_DISC_TYPE_DVDRAM:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdram"))
+            return g_strdup ("gnome-dev-disc-dvdram");
+          goto dvdrom;
+
+dvdr:   case LIBHAL_VOLUME_DISC_TYPE_DVDR:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdr"))
+            return g_strdup ("gnome-dev-disc-dvdr");
+          goto dvdrom;
+
+        case LIBHAL_VOLUME_DISC_TYPE_DVDRW:
+        case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dvdrw"))
+            return g_strdup ("gnome-dev-disc-dvdrw");
+          goto dvdrom;
+
+        case LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR:
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-disc-dev-dvdr-plus"))
+            return g_strdup ("gnome-dev-disc-dev-dvdr-plus");
+          goto dvdr;
+
+        default:
+          /* unsupported disc type */
+          break;
+        }
+      break;
+
+    case LIBHAL_DRIVE_TYPE_FLOPPY:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-floppy"))
+        return g_strdup ("gnome-dev-floppy");
+      break;
+
+    case LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER:
+      if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-ipod"))
+        return g_strdup ("gnome-dev-ipod");
+      break;
+
+    default:
+      /* check if the drive is connected to the USB bus */
+      if (libhal_drive_get_bus (device->drive) == LIBHAL_DRIVE_BUS_USB)
+        {
+          /* we consider the drive to be an USB stick */
+          if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-removable-usb"))
+            return g_strdup ("gnome-dev-removable-usb");
+          else if (gtk_icon_theme_has_icon (icon_theme, "gnome-dev-harddisk-usb"))
+            return g_strdup ("gnome-dev-harddisk-usb");
+        }
+      break;
+    }
+
+  /* generic icon otherwise */
+  return g_strdup ("gnome-fs-blockdev");
+}
+
+
+
+/**
+ * exo_mount_hal_device_is_readonly:
+ * @device : an #ExoMountHalDevice.
+ *
+ * Guesses whether the @device is most probably
+ * a read-only data storage (i.e. a CD-ROM).
+ *
+ * Return value: %TRUE if readonly, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_hal_device_is_readonly (ExoMountHalDevice *device)
+{
+  g_return_val_if_fail (device != NULL, FALSE);
+
+  /* the "volume.is_mounted_read_only" property might be a good start */
+  if (libhal_device_get_property_bool (hal_context, device->udi, "volume.is_mounted_read_only", NULL))
+    return TRUE;
+
+  /* otherwise guess based on the drive type */
+  switch (libhal_drive_get_type (device->drive))
+    {
+    /* CD-ROMs and floppies are read-only... */
+    case LIBHAL_DRIVE_TYPE_CDROM:
+    case LIBHAL_DRIVE_TYPE_FLOPPY:
+      return TRUE;
+
+    /* ...everything else is writable */
+    default:
+      return FALSE;
+    }
+}
+
+
+
+/**
+ * exo_mount_hal_device_eject:
+ * @device : an #ExoMountHalDevice.
+ * @error  : return location for errors or %NULL.
+ *
+ * Ejects the specified @device, returns %TRUE if
+ * successfull, %FALSE if an error occurred.
+ *
+ * Return value: %TRUE if ejected, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_hal_device_eject (ExoMountHalDevice *device,
+                            GError           **error)
+{
+  const gchar **options = { NULL };
+  const guint   n_options = 0;
+  DBusMessage  *message;
+  DBusMessage  *result;
+  DBusError     derror;
+
+  g_return_val_if_fail (device != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* allocate the D-Bus message for the "Eject" method */
+  message = dbus_message_new_method_call ("org.freedesktop.Hal", device->udi, "org.freedesktop.Hal.Device.Volume", "Eject");
+  if (G_UNLIKELY (message == NULL))
+    {
+      /* out of memory */
+oom:  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_strerror (ENOMEM));
+      return FALSE;
+    }
+
+  /* append the (empty) eject options array */
+  if (!dbus_message_append_args (message, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, n_options, DBUS_TYPE_INVALID))
+    {
+      dbus_message_unref (message);
+      goto oom;
+    }
+
+  /* initialize D-Bus error */
+  dbus_error_init (&derror);
+
+  /* send the message to the HAL daemon and block for the reply */
+  result = dbus_connection_send_with_reply_and_block (dbus_connection, message, -1, &derror);
+  if (G_LIKELY (result != NULL))
+    {
+      /* check if an error was returned */
+      if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
+        dbus_set_error_from_message (&derror, result);
+
+      /* release the result */
+      dbus_message_unref (result);
+    }
+
+  /* release the message */
+  dbus_message_unref (message);
+
+  /* check if we failed */
+  if (G_UNLIKELY (dbus_error_is_set (&derror)))
+    {
+      /* try to translate the error appropriately */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied") == 0)
+        {
+          /* TRANSLATORS: The user tried to eject a device although he's not privileged to do so. */
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("You are not privileged to eject the volume \"%s\""), device->name);
+        }
+      else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.Busy") == 0)
+        {
+          /* TRANSLATORS: An application is blocking a mounted volume from being ejected. */
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("An application is preventing the volume \"%s\" from being ejected"), device->name);
+        }
+      else
+        {
+          /* no precise error message, use the HAL one */
+          exo_mount_hal_propagate_error (error, &derror);
+        }
+
+      /* release the DBus error */
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+/**
+ * exo_mount_hal_device_mount:
+ * @device : an #ExoMountHalDevice.
+ * @error  : return location for errors or %NULL.
+ *
+ * Mounts the specified @device and returns %TRUE if
+ * successfull, %FALSE in case of an error.
+ *
+ * Return value: %TRUE if mounted, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_hal_device_mount (ExoMountHalDevice *device,
+                            GError           **error)
+{
+  DBusMessage *message;
+  DBusMessage *result;
+  DBusError    derror;
+  gchar       *mount_point;
+  gchar      **options;
+  gchar       *fstype;
+  gchar       *s;
+  gint         m, n = 0;
+
+  g_return_val_if_fail (device != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* determine the required mount options */
+  options = g_new0 (gchar *, 20);
+  for (m = 0; device->fsoptions[m] != NULL; ++m)
+    {
+      /* this is currently mostly Linux specific noise */
+      if (strcmp (device->fsoptions[m], "uid=") == 0
+          && (strcmp (device->fstype, "vfat") == 0
+           || strcmp (device->fstype, "iso9660") == 0
+           || strcmp (device->fstype, "udf") == 0
+           || device->volume == NULL))
+        {
+          options[n++] = g_strdup_printf ("uid=%u", (guint) getuid ());
+        }
+      else if (strcmp (device->fsoptions[m], "shortname=") == 0
+            && strcmp (device->fstype, "vfat") == 0)
+        {
+          options[n++] = g_strdup_printf ("shortname=winnt");
+        }
+      else if (strcmp (device->fsoptions[m], "sync") == 0
+            && device->volume == NULL)
+        {
+          /* non-pollable drive... */
+          options[n++] = g_strdup ("sync");
+        }
+      else if (strcmp (device->fsoptions[m], "longnames") == 0
+            && strcmp (device->fstype, "vfat") == 0)
+        {
+          /* however this one is FreeBSD specific */
+          options[n++] = g_strdup ("longnames");
+        }
+    }
+
+  /* try to determine a usable mount point */
+  if (G_LIKELY (device->volume != NULL))
+    {
+      /* maybe we can use the volume's label... */
+      mount_point = (gchar *) libhal_volume_get_label (device->volume);
+    }
+  else
+    {
+      /* maybe we can use the the textual type... */
+      mount_point = (gchar *) libhal_drive_get_type_textual (device->drive);
+    }
+
+  /* make sure that the mount point is usable (i.e. does not contain G_DIR_SEPARATOR's) */
+  mount_point = (mount_point != NULL && *mount_point != '\0')
+              ? exo_str_replace (mount_point, G_DIR_SEPARATOR_S, "_") 
+              : g_strdup ("");
+
+  /* let HAL guess the fstype */
+  fstype = g_strdup ("");
+
+  /* setup the D-Bus error */
+  dbus_error_init (&derror);
+
+  /* now several times... */
+  for (;;)
+    {
+      /* prepare the D-Bus message for the "Mount" method */
+      message = dbus_message_new_method_call ("org.freedesktop.Hal", device->udi, "org.freedesktop.Hal.Device.Volume", "Mount");
+      if (G_UNLIKELY (message == NULL))
+        {
+oom:      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_strerror (ENOMEM));
+          g_strfreev (options);
+          g_free (mount_point);
+          g_free (fstype);
+          return FALSE;
+        }
+
+      /* append the message parameters */
+      if (!dbus_message_append_args (message,
+                                     DBUS_TYPE_STRING, &mount_point,
+                                     DBUS_TYPE_STRING, &fstype,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, n,
+				                             DBUS_TYPE_INVALID))
+        {
+          dbus_message_unref (message);
+          goto oom;
+        }
+
+      /* send the message to the HAL daemon */
+      result = dbus_connection_send_with_reply_and_block (dbus_connection, message, -1, &derror);
+      if (G_LIKELY (result != NULL))
+        {
+          /* check if an error was returned */
+          if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
+            dbus_set_error_from_message (&derror, result);
+
+          /* release the result */
+          dbus_message_unref (result);
+        }
+
+      /* release the messages */
+      dbus_message_unref (message);
+
+      /* check if we succeed */
+      if (!dbus_error_is_set (&derror))
+        break;
+
+      /* check if the device was already mounted */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.AlreadyMounted") == 0)
+        {
+          dbus_error_free (&derror);
+          break;
+        }
+
+      /* check if the specified mount point was invalid */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.InvalidMountpoint") == 0 && *mount_point != '\0')
+        {
+          /* try again without a mount point */
+          g_free (mount_point);
+          mount_point = g_strdup ("");
+
+          /* reset the error */
+          dbus_error_free (&derror);
+          continue;
+        }
+
+      /* check if the specified mount point is not available */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.MountPointNotAvailable") == 0 && *mount_point != '\0')
+        {
+          /* try again with a new mount point */
+          s = g_strconcat (mount_point, "_", NULL);
+          g_free (mount_point);
+          mount_point = s;
+
+          /* reset the error */
+          dbus_error_free (&derror);
+          continue;
+        }
+
+#if defined(__FreeBSD__)
+      /* check if an unknown error occurred while trying to mount a floppy */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.UnknownError") == 0
+          && libhal_drive_get_type (device->drive) == LIBHAL_DRIVE_TYPE_FLOPPY)
+        {
+          /* check if no file system type was specified */
+          if (G_LIKELY (*fstype == '\0'))
+            {
+              /* try again with msdosfs */
+              g_free (fstype);
+              fstype = g_strdup ("msdosfs");
+
+              /* reset the error */
+              dbus_error_free (&derror);
+              continue;
+            }
+        }
+#endif
+
+      /* it's also possible that we need to include "ro" in the options */
+      for (n = 0; options[n] != NULL; ++n)
+        if (strcmp (options[n], "ro") == 0)
+          break;
+      if (G_UNLIKELY (options[n] != NULL))
+        {
+          /* we already included "ro" in the options, no way
+           * to mount that device then... we simply give up.
+           */
+          break;
+        }
+
+      /* add "ro" to the options and try again */
+      options[n++] = g_strdup ("ro");
+
+      /* reset the error */
+      dbus_error_free (&derror);
+    }
+
+  /* cleanup */
+  g_strfreev (options);
+  g_free (mount_point);
+  g_free (fstype);
+
+  /* check if we failed */
+  if (dbus_error_is_set (&derror))
+    {
+      /* try to translate the error appropriately */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied") == 0) 
+        {
+          /* TRANSLATORS: User tried to mount a volume, but is not privileged to do so. */
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("You are not privileged to mount the volume \"%s\""), device->name);
+        }
+      else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.AlreadyMounted") == 0)
+        {
+          /* Ups, already mounted, we succeed! */
+          dbus_error_free (&derror);
+          return TRUE;
+        }
+      else
+        {
+          /* unknown error, use HAL's message */
+          exo_mount_hal_propagate_error (error, &derror);
+        }
+
+      /* release D-Bus error */
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+
+/**
+ * exo_mount_hal_device_unmount:
+ * @device : an #ExoMountHalDevice.
+ * @error  : return location for errors or %NULL.
+ *
+ * Unmounts the specified @device and returns %TRUE if
+ * successfull, %FALSE in case of an error.
+ *
+ * Return value: %TRUE if unmounted, %FALSE otherwise.
+ **/
+gboolean
+exo_mount_hal_device_unmount (ExoMountHalDevice *device,
+                              GError           **error)
+{
+  const gchar **options = { NULL };
+  const guint   n_options = 0;
+  DBusMessage  *message;
+  DBusMessage  *result;
+  DBusError     derror;
+
+  g_return_val_if_fail (device != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* allocate the D-Bus message for the "Unmount" method */
+  message = dbus_message_new_method_call ("org.freedesktop.Hal", device->udi, "org.freedesktop.Hal.Device.Volume", "Unmount");
+  if (G_UNLIKELY (message == NULL))
+    {
+      /* out of memory */
+oom:  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, g_strerror (ENOMEM));
+      return FALSE;
+    }
+
+  /* append the (empty) eject options array */
+  if (!dbus_message_append_args (message, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, n_options, DBUS_TYPE_INVALID))
+    {
+      dbus_message_unref (message);
+      goto oom;
+    }
+
+  /* initialize D-Bus error */
+  dbus_error_init (&derror);
+
+  /* send the message to the HAL daemon and block for the reply */
+  result = dbus_connection_send_with_reply_and_block (dbus_connection, message, -1, &derror);
+  if (G_LIKELY (result != NULL))
+    {
+      /* check if an error was returned */
+      if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
+        dbus_set_error_from_message (&derror, result);
+
+      /* release the result */
+      dbus_message_unref (result);
+    }
+
+  /* release the message */
+  dbus_message_unref (message);
+
+  /* check if we failed */
+  if (G_UNLIKELY (dbus_error_is_set (&derror)))
+    {
+      /* try to translate the error appropriately */
+      if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.PermissionDenied") == 0) 
+        {
+          /* TRANSLATORS: User tried to unmount a volume, but is not privileged to do so. */
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("You are not privileged to unmount the volume \"%s\""), device->name);
+        }
+      else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.Busy") == 0)
+        {
+          /* TRANSLATORS: An application is blocking a volume from being unmounted. */
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("An application is preventing the volume \"%s\" from being unmounted"), device->name);
+        }
+      else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.NotMountedByHal") == 0)
+        {
+          /* TRANSLATORS: HAL can only unmount volumes that were mounted via HAL. */
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("The volume \"%s\" was probably mounted manually on the command line"), device->name);
+        }
+      else if (strcmp (derror.name, "org.freedesktop.Hal.Device.Volume.NotMounted") == 0)
+        {
+          /* Ups, volume not mounted, we succeed! */
+          dbus_error_free (&derror);
+          return TRUE;
+        }
+      else
+        {
+          /* unknown error, use the HAL one */
+          exo_mount_hal_propagate_error (error, &derror);
+        }
+
+      /* release the DBus error */
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+


Property changes on: libexo/trunk/exo-mount/exo-mount-hal.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Added: libexo/trunk/exo-mount/exo-mount-hal.h
===================================================================
--- libexo/trunk/exo-mount/exo-mount-hal.h	                        (rev 0)
+++ libexo/trunk/exo-mount/exo-mount-hal.h	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,51 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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 __EXO_MOUNT_HAL_H__
+#define __EXO_MOUNT_HAL_H__
+
+#include <exo/exo.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _ExoMountHalDevice ExoMountHalDevice;
+
+ExoMountHalDevice *exo_mount_hal_device_from_udi    (const gchar       *udi,
+                                                     GError           **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+ExoMountHalDevice *exo_mount_hal_device_from_file   (const gchar       *file,
+                                                     GError           **error) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+void               exo_mount_hal_device_free        (ExoMountHalDevice *device) G_GNUC_INTERNAL;
+
+gchar             *exo_mount_hal_device_get_file    (ExoMountHalDevice *device) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+gchar             *exo_mount_hal_device_get_name    (ExoMountHalDevice *device) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+gchar             *exo_mount_hal_device_get_icon    (ExoMountHalDevice *device) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+gboolean           exo_mount_hal_device_is_readonly (ExoMountHalDevice *device) G_GNUC_INTERNAL;
+
+gboolean           exo_mount_hal_device_eject       (ExoMountHalDevice *device,
+                                                     GError           **error) G_GNUC_INTERNAL;
+gboolean           exo_mount_hal_device_mount       (ExoMountHalDevice *device,
+                                                     GError           **error) G_GNUC_INTERNAL;
+gboolean           exo_mount_hal_device_unmount     (ExoMountHalDevice *device,
+                                                     GError           **error) G_GNUC_INTERNAL;
+
+G_END_DECLS;
+
+#endif /* !__EXO_MOUNT_HAL_H__ */


Property changes on: libexo/trunk/exo-mount/exo-mount-hal.h
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Added: libexo/trunk/exo-mount/exo-mount-utils.c
===================================================================
--- libexo/trunk/exo-mount/exo-mount-utils.c	                        (rev 0)
+++ libexo/trunk/exo-mount/exo-mount-utils.c	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,308 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_UCRED_H
+#include <sys/ucred.h>
+#endif
+#ifdef HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <exo-mount/exo-mount-utils.h>
+
+
+
+static void exo_mount_utils_canonicalize_filename (gchar *filename);
+
+
+
+/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
+static void
+exo_mount_utils_canonicalize_filename (gchar *filename)
+{
+  gboolean last_was_slash = FALSE;
+  gchar   *p = filename;
+  gchar   *q = filename;
+
+  while (*p)
+    {
+      if (*p == G_DIR_SEPARATOR)
+        {
+          if (!last_was_slash)
+            *q++ = G_DIR_SEPARATOR;
+          last_was_slash = TRUE;
+        }
+      else
+        {
+          if (last_was_slash && *p == '.')
+            {
+              if (*(p + 1) == G_DIR_SEPARATOR || *(p + 1) == '\0')
+              {
+                if (*(p + 1) == '\0')
+                  break;
+                
+                p += 1;
+              }
+              else if (*(p + 1) == '.' && (*(p + 2) == G_DIR_SEPARATOR || *(p + 2) == '\0'))
+                {
+                  if (q > filename + 1)
+                    {
+                      q--;
+                      while (q > filename + 1 && *(q - 1) != G_DIR_SEPARATOR)
+                        q--;
+                    }
+                  
+                  if (*(p + 2) == '\0')
+                    break;
+                  
+                  p += 2;
+                }
+              else
+                {
+                  *q++ = *p;
+                  last_was_slash = FALSE;
+                }
+            }
+          else
+            {
+              *q++ = *p;
+              last_was_slash = FALSE;
+            }
+        }
+      
+      p++;
+    }
+  
+  if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
+    q--;
+  
+  *q = '\0';
+}
+
+
+
+/**
+ * exo_mount_utils_resolve:
+ * @device_file     : absolute or relative path to a device file.
+ *
+ * Resolves the @device_file path, which might be a symbolic link
+ * to it's real path. The caller is responsible to free the returned
+ * string using g_free() when no longer needed.
+ *
+ * Return value: the resolved path of the @device_file.
+ **/
+gchar*
+exo_mount_utils_resolve (const gchar *device_file)
+{
+  gchar *dirname;
+  gchar *target;
+  gchar *path;
+
+  g_return_val_if_fail (device_file != NULL, NULL);
+
+  /* check if it's an absolute path */
+  if (!g_path_is_absolute (device_file))
+    path = g_build_filename ("/dev", device_file, NULL);
+  else
+    path = g_strdup (device_file);
+
+  /* resolve all present symlinks */
+  while (g_file_test (path, G_FILE_TEST_IS_SYMLINK))
+    {
+      /* use the path, if we cannot resolve a symlink */
+      target = g_file_read_link (path, NULL);
+      if (G_UNLIKELY (target == NULL))
+        break;
+
+      /* check if the link is relative */
+      if (!g_path_is_absolute (target))
+        {
+          /* relative to the current path then */
+          dirname = g_path_get_dirname (path);
+          g_free (path);
+          path = g_build_filename (dirname, target, NULL);
+          g_free (dirname);
+          g_free (target);
+        }
+      else
+        {
+          /* use the absolute target */
+          g_free (path);
+          path = target;
+        }
+    }
+
+  /* canonicalize the path */
+  exo_mount_utils_canonicalize_filename (path);
+
+  return path;
+}
+
+
+
+/**
+ * exo_mount_utils_is_mounted:
+ * @device_file     : an absolute path to a device file.
+ * @readonly_return : if non-%NULL and the device is mounted, this
+ *                    specifies whether the device was mounted ro.
+ *
+ * Returns %TRUE if the @device_file is already mounted
+ * somewhere in the system, %FALSE otherwise.
+ *
+ * Return value: %TRUE if @device_file is mounted, else %FALSE.
+ **/
+gboolean
+exo_mount_utils_is_mounted (const gchar *device_file,
+                            gboolean    *readonly_return)
+{
+  gboolean result = FALSE;
+  gchar   *resolved;
+
+#if defined(HAVE_SETMNTENT) /* Linux */
+  struct mntent *mntent;
+  FILE          *fp;
+
+  /* try to open the /proc/mounts file */
+  fp = setmntent ("/proc/mounts", "r");
+  if (G_LIKELY (fp != NULL))
+    {
+      /* process all mnt entries */
+      while (!result)
+        {
+          /* read the next entry */
+          mntent = getmntent (fp);
+          if (mntent == NULL)
+            break;
+
+          /* check if this is the entry we are looking for */
+          result = (strcmp (mntent->mnt_fsname, device_file) == 0);
+          if (G_LIKELY (!result))
+            {
+              /* but maybe the mount entry is a symlink */
+              resolved = exo_mount_utils_resolve (mntent->mnt_fsname);
+              result = (strcmp (resolved, device_file) == 0);
+              g_free (resolved);
+            }
+
+          /* check if the device was mounted read-only */
+          if (readonly_return != NULL && result)
+            *readonly_return = (hasmntopt (mntent, "ro") != NULL);
+        }
+
+      /* close the file handle */
+      endmntent (fp);
+    }
+#elif defined(HAVE_GETMNTENT) /* Solaris */
+  struct mnttab mntent;
+  FILE         *fp;
+
+  /* try to open the /proc/mountfs file */
+  fp = fopen ("/proc/mounts", "r");
+  if (G_LIKELY (fp != NULL))
+    {
+      /* process all mnt entries */
+      while (!result)
+        {
+          /* grab the next entry */
+          if (getmntent (fp, &mntent) != 0)
+            break;
+
+          /* check if this is the entry we are looking for */
+          result = (strcmp (mntent.mnt_special, device_file) == 0);
+          if (G_LIKELY (!result))
+            {
+              /* but maybe the mount entry is a symlink */
+              resolved = exo_mount_utils_resolve (mntent.mnt_special);
+              result = (strcmp (resolved, device_file) == 0);
+              g_free (resolved);
+            }
+
+          /* check if the device was mounted read-only */
+          if (readonly_return != NULL && result)
+            *readonly_return = (hasmntopt (&mntent, "ro") != NULL);
+        }
+
+      /* close the file handle */
+      fclose (fp);
+    }
+#elif defined(HAVE_GETFSSTAT) /* FreeBSD */
+  struct statfs *mntbuf = NULL;
+  glong          bufsize = 0;
+  gint           mntsize;
+  gint           n;
+
+  /* determine the number of active mount points */
+  mntsize = getfsstat (NULL, 0, MNT_NOWAIT);
+  if (G_LIKELY (mntsize > 0))
+    {
+      /* allocate a new buffer */
+      bufsize = (mntsize + 4) * sizeof (*mntbuf);
+      mntbuf = (struct statfs *) g_malloc (bufsize);
+
+      /* determine the mount point for the device file */
+      mntsize = getfsstat (mntbuf, bufsize, MNT_NOWAIT);
+      for (n = 0; n < mntsize && !result; ++n)
+        {
+          /* check if this is the entry we are looking for */
+          result = (strcmp (mntbuf[n].f_mntfromname, device_file) == 0);
+          if (G_LIKELY (!result))
+            {
+              /* but maybe the mount entry is a symlink */
+              resolved = exo_mount_utils_resolve (mntbuf[n].f_mntfromname);
+              result = (strcmp (resolved, device_file) == 0);
+              g_free (resolved);
+            }
+
+          /* check if the device was mounted read-only */
+          if (readonly_return != NULL && result)
+            *readonly_return = ((mntbuf[n].f_flags & MNT_RDONLY) != 0);
+        }
+
+      /* release the buffer */
+      g_free (mntbuf);
+    }
+#else
+#error "Add support for your operating system here."
+#endif
+
+  return result;
+}
+
+


Property changes on: libexo/trunk/exo-mount/exo-mount-utils.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Added: libexo/trunk/exo-mount/exo-mount-utils.h
===================================================================
--- libexo/trunk/exo-mount/exo-mount-utils.h	                        (rev 0)
+++ libexo/trunk/exo-mount/exo-mount-utils.h	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,34 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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 __EXO_MOUNT_UTILS_H__
+#define __EXO_MOUNT_UTILS_H__
+
+#include <exo/exo.h>
+
+G_BEGIN_DECLS;
+
+gchar   *exo_mount_utils_resolve    (const gchar *device_file) G_GNUC_INTERNAL G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+gboolean exo_mount_utils_is_mounted (const gchar *device_file,
+                                     gboolean    *readonly_return) G_GNUC_INTERNAL;
+
+G_END_DECLS;
+
+#endif /* !__EXO_MOUNT_UTILS_H__ */


Property changes on: libexo/trunk/exo-mount/exo-mount-utils.h
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Added: libexo/trunk/exo-mount/main.c
===================================================================
--- libexo/trunk/exo-mount/main.c	                        (rev 0)
+++ libexo/trunk/exo-mount/main.c	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,336 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <glib/gstdio.h>
+
+#include <exo-mount/exo-mount-fstab.h>
+#include <exo-mount/exo-mount-hal.h>
+#include <exo-mount/exo-mount-utils.h>
+
+
+
+/* --- globals --- */
+static gboolean opt_eject = FALSE;
+static gboolean opt_unmount = FALSE;
+static gchar   *opt_hal_udi = NULL;
+static gchar   *opt_device = NULL;
+static gboolean opt_noui = FALSE;
+static gboolean opt_version = FALSE;
+
+
+
+/* --- command line options --- */
+static GOptionEntry entries[] =
+{
+  { "eject", 'e', 0, G_OPTION_ARG_NONE, &opt_eject, N_ ("Eject rather than mount"), NULL, },
+  { "unmount", 'u', 0, G_OPTION_ARG_NONE, &opt_unmount, N_ ("Unmount rather than mount"), NULL, },
+#ifdef HAVE_HAL
+  { "hal-udi", 'h', 0, G_OPTION_ARG_STRING, &opt_hal_udi, N_ ("Mount by HAL device UDI"), NULL, },
+#else
+  { "hal-udi", 'h', 0, G_OPTION_ARG_STRING, &opt_hal_udi, N_ ("Mount by HAL device UDI (not supported)"), NULL, },
+#endif
+  { "device", 'd', 0, G_OPTION_ARG_FILENAME, &opt_device, N_ ("Mount by device file"), NULL, },
+  { "no-ui", 'n', 0, G_OPTION_ARG_NONE, &opt_noui, N_ ("Don't show any dialogs"), NULL, },
+  { "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, N_ ("Print version information and exit"), NULL, },
+  { NULL, },
+};
+
+
+
+int
+main (int argc, char **argv)
+{
+#ifdef HAVE_HAL
+  ExoMountHalDevice *device;
+#endif
+  GtkWidget         *dialog;
+  gboolean           mounted_readonly = FALSE;
+  gboolean           mounted;
+  GError            *err = NULL;
+  gchar            **nargv;
+  gchar             *message;
+  gchar             *icon = NULL;
+  gchar             *name = NULL;
+  GPid               pid = 0;
+  gint               n = 0;
+
+  /* initialize the i18n support */
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+  /* initialize GTK+ */
+  if (!gtk_init_with_args (&argc, &argv, "Xfce mount", entries, GETTEXT_PACKAGE, &err))
+    {
+      /* check if we have an error message */
+      if (G_LIKELY (err == NULL))
+        {
+          /* no error message, the GUI initialization failed */
+          const gchar *display_name = gdk_get_display_arg_name ();
+          g_fprintf (stderr, "exo-mount: %s: %s\n", _("Failed to open display"), (display_name != NULL) ? display_name : " ");
+        }
+      else
+        {
+          /* yep, there's an error, so print it */
+          g_fprintf (stderr, "exo-mount: %s\n", err->message);
+        }
+      return EXIT_FAILURE;
+    }
+
+  /* check if we should print version */
+  if (G_UNLIKELY (opt_version))
+    {
+      g_print ("%s %s\n\n", g_get_prgname (), PACKAGE_VERSION);
+      g_print (_("Copyright (c) %s\n"
+                 "        os-cillation e.K. All rights reserved.\n\n"
+                 "Written by Benedikt Meurer <benny at xfce.org>.\n\n"),
+               "2006-2007");
+      g_print (_("%s comes with ABSOLUTELY NO WARRANTY,\n"
+                 "You may redistribute copies of %s under the terms of\n"
+                 "the GNU Lesser General Public License which can be found in the\n"
+                 "%s source package.\n\n"), g_get_prgname (), g_get_prgname (), PACKAGE_TARNAME);
+      g_print (_("Please report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+      return EXIT_SUCCESS;
+    }
+
+  /* make sure that either a device UDI or file was specified... */
+  if (G_UNLIKELY (opt_hal_udi == NULL && opt_device == NULL))
+    {
+      /* the caller must specify either a HAL UDI or a device file */
+      g_printerr ("%s: %s.\n", g_get_prgname (), _("Must specify HAL device UDI or device file"));
+      return EXIT_FAILURE;
+    }
+
+  /* ...but not both an UDI and a device file */
+  if (G_UNLIKELY (opt_hal_udi != NULL && opt_device != NULL))
+    {
+      /* the caller must specify EITHER a HAL UDI or a device file */
+      g_printerr ("%s: %s.\n", g_get_prgname (), _("Must not specify both a HAL device UDI and a device file simultaneously"));
+      return EXIT_FAILURE;
+    }
+
+#ifndef HAVE_HAL
+  /* cannot mount by UDI if HAL is not available */
+  if (G_UNLIKELY (opt_hal_udi != NULL))
+    {
+      g_printerr ("%s: %s.\n", g_get_prgname (), _("Cannot mount by HAL device UDI, because HAL support was disabled for this build"));
+      return EXIT_FAILURE;
+    }
+#endif
+
+  /* infer operation from program name */
+  if (strcmp (g_get_prgname (), "exo-unmount") == 0)
+    opt_unmount = TRUE;
+  else if (strcmp (g_get_prgname (), "exo-eject") == 0)
+    opt_eject = TRUE;
+
+  /* verify that only a single option was specified */
+  if (G_UNLIKELY (opt_eject && opt_unmount))
+    {
+      /* the caller must not specify both eject and unmount */
+      g_printerr ("%s: %s.\n", g_get_prgname (), _("Cannot eject and unmount simultaneously"));
+      return EXIT_FAILURE;
+    }
+
+  /* resolve the device file path */
+  if (G_UNLIKELY (opt_device != NULL))
+    opt_device = exo_mount_utils_resolve (opt_device);
+
+#ifdef HAVE_HAL
+  /* query the device information from the HAL daemon */
+  device = (opt_device != NULL)
+         ? exo_mount_hal_device_from_file (opt_device, &err)
+         : exo_mount_hal_device_from_udi (opt_hal_udi, &err);
+  if (G_UNLIKELY (device == NULL))
+    goto err0;
+
+  /* determine the device file from the device struct */
+  opt_device = exo_mount_hal_device_get_file (device);
+
+  /* resolve the device file path (again) */
+  opt_device = exo_mount_utils_resolve (opt_device);
+
+  /* determine name and icon of the device */
+  icon = exo_mount_hal_device_get_icon (device);
+  name = exo_mount_hal_device_get_name (device);
+
+  /* check if the device is most probably a read-only device */
+  mounted_readonly = exo_mount_hal_device_is_readonly (device);
+#endif
+
+  /* check if the device is currently mounted */
+  mounted = exo_mount_utils_is_mounted (opt_device, &mounted_readonly);
+  if ((!opt_eject && !opt_unmount && mounted)
+      || (opt_unmount && !mounted))
+    {
+      /* pretend that we succeed */
+      return EXIT_SUCCESS;
+    }
+
+  /* check if a name was found */
+  if (G_UNLIKELY (name == NULL || *name == '\0'))
+    {
+      /* release the previous name */
+      g_free (name);
+
+      /* default to the path of the device file */
+      name = g_filename_display_name (opt_device);
+    }
+
+  /* check if we should display a notification */
+  if ((opt_eject && mounted) || opt_unmount)
+    {
+      /* prepare arguments for the unmount notification */
+      nargv = g_new (gchar *, 8);
+      nargv[n++] = g_strdup (LIBEXECDIR G_DIR_SEPARATOR_S "exo-mount-notify-" LIBEXO_VERSION_API);
+      if (mounted_readonly)
+        {
+          nargv[n++] = g_strdup ("--readonly");
+        }
+      if (opt_eject)
+        {
+          nargv[n++] = g_strdup ("--eject");
+        }
+      if (icon != NULL && *icon != '\0')
+        {
+          nargv[n++] = g_strdup ("--icon");
+          nargv[n++] = g_strdup (icon);
+        }
+      nargv[n++] = g_strdup ("--name");
+      nargv[n++] = g_strdup (name);
+      nargv[n] = NULL;
+
+      /* try to spawn the unmount notification */
+      if (!gdk_spawn_on_screen (gdk_screen_get_default (), NULL, nargv, NULL, 0, NULL, NULL, &pid, NULL))
+        {
+          /* failed to spawn, don't worry,
+           * just remember this fact...
+           */
+          pid = 0;
+        }
+
+      /* cleanup */
+      g_strfreev (nargv);
+    }
+
+  /* check if the device appears in the fstab,
+   * if so, we cannot use HAL to mount it.
+   */
+#ifdef HAVE_HAL
+  if (!exo_mount_fstab_contains (opt_device))
+    {
+      /* perform the requested operation */
+      if (G_LIKELY (opt_unmount))
+        exo_mount_hal_device_unmount (device, &err);
+      else if (G_LIKELY (opt_eject))
+        exo_mount_hal_device_eject (device, &err);
+      else
+        exo_mount_hal_device_mount (device, &err);
+    }
+  else
+#endif
+    {
+      /* perform the requested operation */
+      if (G_LIKELY (opt_unmount))
+        exo_mount_fstab_unmount (opt_device, &err);
+      else if (G_LIKELY (opt_eject))
+        exo_mount_fstab_eject (opt_device, &err);
+      else
+        exo_mount_fstab_mount (opt_device, &err);
+    }
+
+  /* check if we have a notification process to kill */
+  if (G_LIKELY (pid != 0))
+    {
+      /* send SIGUSR1 if we succeed, SIGTERM otherwise */
+      kill (pid, (err == NULL) ? SIGUSR1 : SIGTERM);
+
+      /* cleanup the PID */
+      g_spawn_close_pid (pid);
+    }
+
+  /* check if we failed */
+  if (G_UNLIKELY (err != NULL))
+    {
+err0: /* check if we should display an error dialog */
+      if (G_LIKELY (!opt_noui))
+        {
+          /* make sure we can display a name */
+          if (G_UNLIKELY (name == NULL))
+            {
+              /* either device file or UDI */
+              if (G_LIKELY (opt_device != NULL))
+                name = g_filename_display_name (opt_device);
+              else
+                name = g_strdup (opt_hal_udi);
+            }
+
+          /* determine the appropriate error message */
+          if (G_LIKELY (opt_eject))
+            message = g_strdup_printf (_("Failed to eject \"%s\""), name);
+          else if (G_LIKELY (opt_unmount))
+            message = g_strdup_printf (_("Failed to unmount \"%s\""), name);
+          else
+            message = g_strdup_printf (_("Failed to mount \"%s\""), name);
+
+          /* popup an error message dialog */
+          dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s.", message);
+          gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s.", err->message);
+          gtk_dialog_run (GTK_DIALOG (dialog));
+          gtk_widget_destroy (dialog);
+          g_free (message);
+        }
+      else
+        {
+          /* otherwise, it's probably called from thunar-vfs,
+           * so print the error message to standard error.
+           */
+          g_printerr ("%s.\n", err->message);
+        }
+
+      /* release the error */
+      g_error_free (err);
+    }
+
+  /* cleanup */
+  g_free (name);
+  g_free (icon);
+
+  return (err == NULL) ? EXIT_SUCCESS : EXIT_FAILURE;
+}


Property changes on: libexo/trunk/exo-mount/main.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev


Property changes on: libexo/trunk/exo-mount-notify
___________________________________________________________________
Name: svn:ignore
   + .deps
.libs
Makefile
Makefile.in
exo-mount-notify-0.3


Copied: libexo/trunk/exo-mount-notify/Makefile.am (from rev 24254, libexo/trunk/exo-open/Makefile.am)
===================================================================
--- libexo/trunk/exo-mount-notify/Makefile.am	                        (rev 0)
+++ libexo/trunk/exo-mount-notify/Makefile.am	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,30 @@
+# $Id$
+
+INCLUDES = 								\
+	-I$(top_srcdir)							\
+	-DG_LOG_DOMAIN=\"exo-mount-notify\"				\
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"
+
+libexec_PROGRAMS =							\
+	exo-mount-notify-0.3
+
+exo_mount_notify_0_3_SOURCES =						\
+	main.c
+
+exo_mount_notify_0_3_CFLAGS =						\
+	$(GTK_CFLAGS)							\
+	$(LIBNOTIFY_CFLAGS)						\
+	$(LIBXFCE4UTIL_CFLAGS)
+
+exo_mount_notify_0_3_LDFLAGS =						\
+	-no-undefined
+
+exo_mount_notify_0_3_LDADD =						\
+	$(GTK_LIBS)							\
+	$(LIBNOTIFY_LIBS)						\
+	$(LIBXFCE4UTIL_LIBS)
+
+EXTRA_DIST =								\
+	README
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

Added: libexo/trunk/exo-mount-notify/README
===================================================================
--- libexo/trunk/exo-mount-notify/README	                        (rev 0)
+++ libexo/trunk/exo-mount-notify/README	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,10 @@
+What is this?
+=============
+
+exo-mount-notify is a small, internal utility used by exo-mount to display a
+notification while unmounting/ejecting devices and a hint after a device was
+unmounted that the user can remove the device.
+
+This utility requires libnotify and a running notification daemon. exo-mount
+will work even if exo-mount-notify is not installed, so libnotify is a soft
+dependency.

Added: libexo/trunk/exo-mount-notify/main.c
===================================================================
--- libexo/trunk/exo-mount-notify/main.c	                        (rev 0)
+++ libexo/trunk/exo-mount-notify/main.c	2007-01-06 18:09:04 UTC (rev 24275)
@@ -0,0 +1,260 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2006-2007 Benedikt Meurer <benny at xfce.org>.
+ *
+ * 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 of the License, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <libnotify/notify.h>
+
+#include <glib/gstdio.h>
+
+#include <gtk/gtk.h>
+
+/* make sure all defines are present */
+#ifndef NOTIFY_EXPIRES_NEVER
+#define NOTIFY_EXPIRES_NEVER 0
+#endif
+#ifndef NOTIFY_EXPIRES_DEFAULT
+#define NOTIFY_EXPIRES_DEFAULT -1
+#endif
+
+
+
+/* --- globals --- */
+static gboolean            opt_eject = FALSE;
+static gchar              *opt_icon = NULL;
+static gchar              *opt_name = NULL;
+static gboolean            opt_readonly = FALSE;
+static gboolean            opt_version = FALSE;
+static gint                signal_fds[2];
+static NotifyNotification *notification = NULL;
+
+
+
+/* --- command line options --- */
+static GOptionEntry entries[] =
+{
+  { "eject", 'e', 0, G_OPTION_ARG_NONE, &opt_eject, NULL, NULL, },
+  { "icon", 'i', 0, G_OPTION_ARG_STRING, &opt_icon, NULL, NULL, },
+  { "name", 'n', 0, G_OPTION_ARG_STRING, &opt_name, NULL, NULL, },
+  { "readonly", 'r', 0, G_OPTION_ARG_NONE, &opt_readonly, NULL, NULL, },
+  { "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, N_ ("Print version information and exit"), NULL, },
+  { NULL, },
+};
+
+
+
+static void
+signal_func (int signo)
+{
+  /* SIGUSR1 means success */
+  write (signal_fds[1], (signo == SIGUSR1) ? "U" : "K", 1);
+}
+
+
+
+static gboolean
+signal_io_func (GIOChannel  *channel,
+                GIOCondition condition,
+                gpointer     user_data)
+{
+  gchar *message;
+  gchar  c;
+
+  /* read the first character from signal pipe */
+  if (read (signal_fds[0], &c, 1) < 1)
+    return TRUE;
+
+  /* perform the appropriate operation */
+  if (c == 'U') /* SIGUSR1 */
+    {
+      /* the operation succeed */
+      if (G_LIKELY (!opt_eject))
+        {
+          /* tell the user that the device can be removed now */
+          message = g_strdup_printf (_("The device \"%s\" is now safe to remove."), opt_name);
+          notify_notification_update (notification, _("Device is now safe to remove"), message, opt_icon);
+          notify_notification_set_timeout (notification, NOTIFY_EXPIRES_DEFAULT);
+          notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+          notify_notification_show (notification, NULL);
+          g_free (message);
+
+          /* we don't care for the pipe anymore */
+          return FALSE;
+        }
+    }
+
+  /* bring down the notification */
+  gtk_main_quit ();
+
+  return TRUE;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+  const gchar *summary;
+  GIOChannel  *channel;
+  GError      *err = NULL;
+  gchar       *message;
+
+  /* initialize the i18n support */
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+  /* initialize GTK+ */
+  if (!gtk_init_with_args (&argc, &argv, "Xfce Mount Notify", entries, GETTEXT_PACKAGE, &err))
+    {
+      /* check if we have an error message */
+      if (G_LIKELY (err == NULL))
+        {
+          /* no error message, the GUI initialization failed */
+          const gchar *display_name = gdk_get_display_arg_name ();
+          g_fprintf (stderr, "exo-mount-notify: %s: %s\n", _("Failed to open display"), (display_name != NULL) ? display_name : " ");
+        }
+      else
+        {
+          /* yep, there's an error, so print it */
+          g_fprintf (stderr, "exo-mount-notify: %s\n", err->message);
+        }
+      return EXIT_FAILURE;
+    }
+
+  /* check if we should print version */
+  if (G_UNLIKELY (opt_version))
+    {
+      g_print ("%s %s\n\n", g_get_prgname (), PACKAGE_VERSION);
+      g_print (_("Copyright (c) %s\n"
+                 "        os-cillation e.K. All rights reserved.\n\n"
+                 "Written by Benedikt Meurer <benny at xfce.org>.\n\n"),
+               "2006-2007");
+      g_print (_("%s comes with ABSOLUTELY NO WARRANTY,\n"
+                 "You may redistribute copies of %s under the terms of\n"
+                 "the GNU Lesser General Public License which can be found in the\n"
+                 "%s source package.\n\n"), g_get_prgname (), g_get_prgname (), PACKAGE_TARNAME);
+      g_print (_("Please report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+      return EXIT_SUCCESS;
+    }
+
+  /* icon defaults to "gnome-dev-harddisk" */
+  if (G_UNLIKELY (opt_icon == NULL || *opt_icon == '\0'))
+    opt_icon = "gnome-dev-harddisk";
+
+  /* make sure that a device name was specified */
+  if (G_UNLIKELY (opt_name == NULL || *opt_name == '\0'))
+    {
+      /* the caller must specify a usable device name */
+      g_printerr ("%s: %s.\n", g_get_prgname (), "Must specify a device name");
+      return EXIT_FAILURE;
+    }
+
+  /* try to initialize libnotify */
+  if (!notify_init ("exo-mount"))
+    {
+      /* it doesn't make sense to continue from here on */
+      g_printerr ("%s: %s.\n", g_get_prgname (), "Failed to initialize libnotify");
+      return EXIT_FAILURE;
+    }
+
+  /* setup the signal pipe */
+  if (pipe (signal_fds) < 0)
+    {
+      g_printerr ("%s: Failed to setup signal pipe: %s.\n", g_get_prgname (), g_strerror (errno));
+      return EXIT_FAILURE;
+    }
+
+  /* register the appropriate signal handlers */
+  signal (SIGTERM, signal_func);
+  signal (SIGHUP, signal_func);
+  signal (SIGINT, signal_func);
+  signal (SIGUSR1, signal_func);
+
+  /* watch the read side of the signal pipe */
+  channel = g_io_channel_unix_new (signal_fds[0]);
+  g_io_add_watch (channel, G_IO_IN, signal_io_func, NULL);
+  g_io_channel_unref (channel);
+
+  /* different summary/message based on whether it's readonly */
+  if (G_UNLIKELY (opt_readonly))
+    {
+      /* check if we eject */
+      if (G_LIKELY (opt_eject))
+        {
+          /* read-only, just ejecting */
+          summary = _("Ejecting device");
+          message = g_strdup_printf (_("The device \"%s\" is being ejected. This may take some time."), opt_name);
+        }
+      else
+        {
+          /* read-only, just unmounting */
+          summary = _("Unmounting device");
+          message = g_strdup_printf (_("The device \"%s\" is being unmounted by the system. Please do "
+                                       "not remove the media or disconnect the drive."), opt_name);
+        }
+    }
+  else
+    {
+      /* not read-only, writing back data */
+      summary = _("Writing data to device");
+      message = g_strdup_printf (_("There is data that needs to be written to the device \"%s\" before it can be "
+                                   "removed. Please do not remove the media or disconnect the drive."), opt_name);
+    }
+
+  /* setup the notification */
+  notification = notify_notification_new (summary, message, opt_icon, NULL);
+  g_signal_connect (G_OBJECT (notification), "closed", G_CALLBACK (gtk_main_quit), NULL);
+  g_object_add_weak_pointer (G_OBJECT (notification), (gpointer) &notification);
+  notify_notification_set_urgency (notification, NOTIFY_URGENCY_CRITICAL);
+  notify_notification_set_timeout (notification, NOTIFY_EXPIRES_NEVER);
+  notify_notification_show (notification, NULL);
+  g_free (message);
+
+  /* enter the main loop */
+  gtk_main ();
+
+  /* release the notification */
+  if (G_LIKELY (notification != NULL))
+    {
+      notify_notification_close (notification, NULL);
+      g_object_unref (G_OBJECT (notification));
+    }
+
+  return EXIT_SUCCESS;
+}


Property changes on: libexo/trunk/exo-mount-notify/main.c
___________________________________________________________________
Name: svn:keywords
   + Author Date Id Rev

Modified: libexo/trunk/po/ChangeLog
===================================================================
--- libexo/trunk/po/ChangeLog	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/po/ChangeLog	2007-01-06 18:09:04 UTC (rev 24275)
@@ -1,3 +1,9 @@
+2007-01-06  Benedikt Meurer <benny at xfce.org>
+
+	* POTFILES.in: Add new files here.
+	* libexo-0.3.pot, *.po: Merge new strings.
+	* de.po: Update german translations.
+
 2007-01-05  Maximilian Schleiss <maxschleiss at bluewin.ch>
 
 	* fr.po: Updated the French translation.
@@ -4,7 +10,7 @@
 
 2007-01-04  Piarres Beobide <pi at beobide.net>
 
-        * eu.po: Updated Basque translation.
+	* eu.po: Updated Basque translation.
 
 2007-01-03  Benedikt Meurer <benny at xfce.org>
 

Modified: libexo/trunk/po/POTFILES.in
===================================================================
--- libexo/trunk/po/POTFILES.in	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/po/POTFILES.in	2007-01-06 18:09:04 UTC (rev 24275)
@@ -73,5 +73,12 @@
 exo-helper/helpers/w3m.desktop.in.in
 exo-helper/helpers/xterm.desktop.in.in
 
+exo-mount/exo-mount-fstab.c
+exo-mount/exo-mount-hal.c
+exo-mount/exo-mount-utils.c
+exo-mount/main.c
+
+exo-mount-notify/main.c
+
 exo-open/main.c
 

Modified: libexo/trunk/po/ca.po
===================================================================
--- libexo/trunk/po/ca.po	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/po/ca.po	2007-01-06 18:09:04 UTC (rev 24275)
@@ -9,7 +9,7 @@
 msgstr ""
 "Project-Id-Version: exo 0.3.1.12rc2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-01-03 13:02+0100\n"
+"POT-Creation-Date: 2007-01-06 18:44+0100\n"
 "PO-Revision-Date: 2006-09-18 21:22+0200\n"
 "Last-Translator: Carles Muñoz Gorriz <carlesmu at internautas.org>\n"
 "Language-Team: Catalan\n"
@@ -45,7 +45,8 @@
 msgid "The size of the icon to render in pixels."
 msgstr "Tamany en píxels de la icona a representar"
 
-#: ../exo/exo-gdk-pixbuf-extensions.c:770
+#: ../exo/exo-gdk-pixbuf-extensions.c:770 ../exo-mount/exo-mount-fstab.c:146
+#: ../exo-mount/exo-mount-fstab.c:187
 #, c-format
 msgid "Failed to open file \"%s\": %s"
 msgstr "No s'ha pogut obrir «%s»: %s"
@@ -516,6 +517,7 @@
 msgstr "  --build-list      Analitza parelles (nom, fitxer)\n"
 
 #: ../exo-csource/main.c:248 ../exo-desktop-item-edit/main.c:153
+#: ../exo-mount/main.c:120 ../exo-mount-notify/main.c:164
 #: ../exo-open/main.c:129
 #, fuzzy, c-format
 msgid ""
@@ -532,6 +534,7 @@
 "\n"
 
 #: ../exo-csource/main.c:252 ../exo-desktop-item-edit/main.c:157
+#: ../exo-mount/main.c:124 ../exo-mount-notify/main.c:168
 #: ../exo-open/main.c:133
 #, c-format
 msgid ""
@@ -548,6 +551,7 @@
 "\n"
 
 #: ../exo-csource/main.c:256 ../exo-desktop-item-edit/main.c:161
+#: ../exo-mount/main.c:128 ../exo-mount-notify/main.c:172
 #: ../exo-open/main.c:137
 #, c-format
 msgid "Please report bugs to <%s>.\n"
@@ -708,7 +712,8 @@
 msgid "Preset icon when creating a desktop file"
 msgstr "Preselecciona la icona de creació de fitxers d'escriptori"
 
-#: ../exo-desktop-item-edit/main.c:79
+#: ../exo-desktop-item-edit/main.c:79 ../exo-mount/main.c:72
+#: ../exo-mount-notify/main.c:77
 msgid "Print version information and exit"
 msgstr "Imprimeix informació sobre la versió i surt"
 
@@ -717,9 +722,10 @@
 msgid "[FILE|FOLDER]"
 msgstr "[FITXER|CARPETA]"
 
-#: ../exo-desktop-item-edit/main.c:138
-#, c-format
-msgid "Failed to open display: %s"
+#: ../exo-desktop-item-edit/main.c:138 ../exo-mount/main.c:106
+#: ../exo-mount-notify/main.c:150
+#, fuzzy
+msgid "Failed to open display"
 msgstr "No s'ha pogut obrir la pantalla: %s"
 
 #: ../exo-desktop-item-edit/main.c:168
@@ -1064,6 +1070,163 @@
 msgid "X Terminal"
 msgstr "Terminal X"
 
+#: ../exo-mount/exo-mount-fstab.c:112
+msgid "Unknown error"
+msgstr ""
+
+#. generate an appropriate error message
+#. tell the caller that no matching device was found
+#: ../exo-mount/exo-mount-fstab.c:248 ../exo-mount/exo-mount-hal.c:339
+#, c-format
+msgid "Device \"%s\" not found in file system device table"
+msgstr ""
+
+#. definitely not a device that we're able to mount, eject or unmount
+#: ../exo-mount/exo-mount-hal.c:193 ../exo-mount/exo-mount-hal.c:246
+#, c-format
+msgid "Given device \"%s\" is not a volume or drive"
+msgstr ""
+
+#. TRANSLATORS: The user tried to eject a device although he's not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:616
+#, c-format
+msgid "You are not privileged to eject the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: An application is blocking a mounted volume from being ejected.
+#: ../exo-mount/exo-mount-hal.c:621
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being ejected"
+msgstr ""
+
+#. TRANSLATORS: User tried to mount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:846
+#, c-format
+msgid "You are not privileged to mount the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: User tried to unmount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:935
+#, c-format
+msgid "You are not privileged to unmount the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: An application is blocking a volume from being unmounted.
+#: ../exo-mount/exo-mount-hal.c:940
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being unmounted"
+msgstr ""
+
+#. TRANSLATORS: HAL can only unmount volumes that were mounted via HAL.
+#: ../exo-mount/exo-mount-hal.c:945
+#, c-format
+msgid "The volume \"%s\" was probably mounted manually on the command line"
+msgstr ""
+
+#: ../exo-mount/main.c:63
+msgid "Eject rather than mount"
+msgstr ""
+
+#: ../exo-mount/main.c:64
+msgid "Unmount rather than mount"
+msgstr ""
+
+#: ../exo-mount/main.c:66
+msgid "Mount by HAL device UDI"
+msgstr ""
+
+#: ../exo-mount/main.c:68
+msgid "Mount by HAL device UDI (not supported)"
+msgstr ""
+
+#: ../exo-mount/main.c:70
+msgid "Mount by device file"
+msgstr ""
+
+#: ../exo-mount/main.c:71
+msgid "Don't show any dialogs"
+msgstr ""
+
+#. the caller must specify either a HAL UDI or a device file
+#: ../exo-mount/main.c:136
+msgid "Must specify HAL device UDI or device file"
+msgstr ""
+
+#. the caller must specify EITHER a HAL UDI or a device file
+#: ../exo-mount/main.c:144
+msgid "Must not specify both a HAL device UDI and a device file simultaneously"
+msgstr ""
+
+#: ../exo-mount/main.c:152
+msgid ""
+"Cannot mount by HAL device UDI, because HAL support was disabled for this "
+"build"
+msgstr ""
+
+#. the caller must not specify both eject and unmount
+#: ../exo-mount/main.c:167
+msgid "Cannot eject and unmount simultaneously"
+msgstr ""
+
+#: ../exo-mount/main.c:306
+#, fuzzy, c-format
+msgid "Failed to eject \"%s\""
+msgstr "No s'ha pogut crear «%s»."
+
+#: ../exo-mount/main.c:308
+#, fuzzy, c-format
+msgid "Failed to unmount \"%s\""
+msgstr "No s'ha pogut obrir «%s»."
+
+#: ../exo-mount/main.c:310
+#, fuzzy, c-format
+msgid "Failed to mount \"%s\""
+msgstr "No s'ha pogut obrir «%s»."
+
+#. tell the user that the device can be removed now
+#: ../exo-mount-notify/main.c:111
+#, c-format
+msgid "The device \"%s\" is now safe to remove."
+msgstr ""
+
+#: ../exo-mount-notify/main.c:112
+msgid "Device is now safe to remove"
+msgstr ""
+
+#. read-only, just ejecting
+#: ../exo-mount-notify/main.c:221
+msgid "Ejecting device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:222
+#, c-format
+msgid "The device \"%s\" is being ejected. This may take some time."
+msgstr ""
+
+#. read-only, just unmounting
+#: ../exo-mount-notify/main.c:227
+msgid "Unmounting device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:228
+#, c-format
+msgid ""
+"The device \"%s\" is being unmounted by the system. Please do not remove the "
+"media or disconnect the drive."
+msgstr ""
+
+#. not read-only, writing back data
+#: ../exo-mount-notify/main.c:235
+msgid "Writing data to device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:236
+#, c-format
+msgid ""
+"There is data that needs to be written to the device \"%s\" before it can be "
+"removed. Please do not remove the media or disconnect the drive."
+msgstr ""
+
 #: ../exo-open/main.c:59
 msgid "Usage: exo-open [URLs...]"
 msgstr "Ús: exo-open [URLs…]"
@@ -1145,3 +1308,6 @@
 #, c-format
 msgid "Failed to open URL \"%s\"."
 msgstr "No s'ha pogut obrir la URL «%s»"
+
+#~ msgid "Failed to open display: %s"
+#~ msgstr "No s'ha pogut obrir la pantalla: %s"

Modified: libexo/trunk/po/cs.po
===================================================================
--- libexo/trunk/po/cs.po	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/po/cs.po	2007-01-06 18:09:04 UTC (rev 24275)
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: exo 0.3.1.12rc2\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-01-03 13:02+0100\n"
+"POT-Creation-Date: 2007-01-06 18:44+0100\n"
 "PO-Revision-Date: 2006-09-16 11:19+0100\n"
 "Last-Translator: Michal Várady <miko.vaji at gmail.com>\n"
 "Language-Team: Czech <translation-team-cs at lists.sourceforge.net>\n"
@@ -45,7 +45,8 @@
 msgid "The size of the icon to render in pixels."
 msgstr "Velikost vykreslené ikony v obrazových bodech."
 
-#: ../exo/exo-gdk-pixbuf-extensions.c:770
+#: ../exo/exo-gdk-pixbuf-extensions.c:770 ../exo-mount/exo-mount-fstab.c:146
+#: ../exo-mount/exo-mount-fstab.c:187
 #, c-format
 msgid "Failed to open file \"%s\": %s"
 msgstr "Nepodařilo se otevřít soubor \"%s\": %s"
@@ -514,6 +515,7 @@
 msgstr "  --build-list      Parsovací páry (název, soubor)\n"
 
 #: ../exo-csource/main.c:248 ../exo-desktop-item-edit/main.c:153
+#: ../exo-mount/main.c:120 ../exo-mount-notify/main.c:164
 #: ../exo-open/main.c:129
 #, fuzzy, c-format
 msgid ""
@@ -530,6 +532,7 @@
 "\n"
 
 #: ../exo-csource/main.c:252 ../exo-desktop-item-edit/main.c:157
+#: ../exo-mount/main.c:124 ../exo-mount-notify/main.c:168
 #: ../exo-open/main.c:133
 #, c-format
 msgid ""
@@ -546,6 +549,7 @@
 "\n"
 
 #: ../exo-csource/main.c:256 ../exo-desktop-item-edit/main.c:161
+#: ../exo-mount/main.c:128 ../exo-mount-notify/main.c:172
 #: ../exo-open/main.c:137
 #, c-format
 msgid "Please report bugs to <%s>.\n"
@@ -713,7 +717,8 @@
 "Přednastavená ikona při vytváření souboru na\n"
 "                              ploše"
 
-#: ../exo-desktop-item-edit/main.c:79
+#: ../exo-desktop-item-edit/main.c:79 ../exo-mount/main.c:72
+#: ../exo-mount-notify/main.c:77
 msgid "Print version information and exit"
 msgstr "Zobrazí informace o verzi a ukončí se"
 
@@ -722,9 +727,10 @@
 msgid "[FILE|FOLDER]"
 msgstr "[SOUBOR|ADRESÁŘ]"
 
-#: ../exo-desktop-item-edit/main.c:138
-#, c-format
-msgid "Failed to open display: %s"
+#: ../exo-desktop-item-edit/main.c:138 ../exo-mount/main.c:106
+#: ../exo-mount-notify/main.c:150
+#, fuzzy
+msgid "Failed to open display"
 msgstr "Nepodařilo se otevřít displej: %s"
 
 #: ../exo-desktop-item-edit/main.c:168
@@ -1070,6 +1076,163 @@
 msgid "X Terminal"
 msgstr "X Terminál"
 
+#: ../exo-mount/exo-mount-fstab.c:112
+msgid "Unknown error"
+msgstr ""
+
+#. generate an appropriate error message
+#. tell the caller that no matching device was found
+#: ../exo-mount/exo-mount-fstab.c:248 ../exo-mount/exo-mount-hal.c:339
+#, c-format
+msgid "Device \"%s\" not found in file system device table"
+msgstr ""
+
+#. definitely not a device that we're able to mount, eject or unmount
+#: ../exo-mount/exo-mount-hal.c:193 ../exo-mount/exo-mount-hal.c:246
+#, c-format
+msgid "Given device \"%s\" is not a volume or drive"
+msgstr ""
+
+#. TRANSLATORS: The user tried to eject a device although he's not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:616
+#, c-format
+msgid "You are not privileged to eject the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: An application is blocking a mounted volume from being ejected.
+#: ../exo-mount/exo-mount-hal.c:621
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being ejected"
+msgstr ""
+
+#. TRANSLATORS: User tried to mount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:846
+#, c-format
+msgid "You are not privileged to mount the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: User tried to unmount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:935
+#, c-format
+msgid "You are not privileged to unmount the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: An application is blocking a volume from being unmounted.
+#: ../exo-mount/exo-mount-hal.c:940
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being unmounted"
+msgstr ""
+
+#. TRANSLATORS: HAL can only unmount volumes that were mounted via HAL.
+#: ../exo-mount/exo-mount-hal.c:945
+#, c-format
+msgid "The volume \"%s\" was probably mounted manually on the command line"
+msgstr ""
+
+#: ../exo-mount/main.c:63
+msgid "Eject rather than mount"
+msgstr ""
+
+#: ../exo-mount/main.c:64
+msgid "Unmount rather than mount"
+msgstr ""
+
+#: ../exo-mount/main.c:66
+msgid "Mount by HAL device UDI"
+msgstr ""
+
+#: ../exo-mount/main.c:68
+msgid "Mount by HAL device UDI (not supported)"
+msgstr ""
+
+#: ../exo-mount/main.c:70
+msgid "Mount by device file"
+msgstr ""
+
+#: ../exo-mount/main.c:71
+msgid "Don't show any dialogs"
+msgstr ""
+
+#. the caller must specify either a HAL UDI or a device file
+#: ../exo-mount/main.c:136
+msgid "Must specify HAL device UDI or device file"
+msgstr ""
+
+#. the caller must specify EITHER a HAL UDI or a device file
+#: ../exo-mount/main.c:144
+msgid "Must not specify both a HAL device UDI and a device file simultaneously"
+msgstr ""
+
+#: ../exo-mount/main.c:152
+msgid ""
+"Cannot mount by HAL device UDI, because HAL support was disabled for this "
+"build"
+msgstr ""
+
+#. the caller must not specify both eject and unmount
+#: ../exo-mount/main.c:167
+msgid "Cannot eject and unmount simultaneously"
+msgstr ""
+
+#: ../exo-mount/main.c:306
+#, fuzzy, c-format
+msgid "Failed to eject \"%s\""
+msgstr "Nepodařilo se vytvořit \"%s\"."
+
+#: ../exo-mount/main.c:308
+#, fuzzy, c-format
+msgid "Failed to unmount \"%s\""
+msgstr "Nepodařilo se otevřít \"%s\"."
+
+#: ../exo-mount/main.c:310
+#, fuzzy, c-format
+msgid "Failed to mount \"%s\""
+msgstr "Nepodařilo se otevřít \"%s\"."
+
+#. tell the user that the device can be removed now
+#: ../exo-mount-notify/main.c:111
+#, c-format
+msgid "The device \"%s\" is now safe to remove."
+msgstr ""
+
+#: ../exo-mount-notify/main.c:112
+msgid "Device is now safe to remove"
+msgstr ""
+
+#. read-only, just ejecting
+#: ../exo-mount-notify/main.c:221
+msgid "Ejecting device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:222
+#, c-format
+msgid "The device \"%s\" is being ejected. This may take some time."
+msgstr ""
+
+#. read-only, just unmounting
+#: ../exo-mount-notify/main.c:227
+msgid "Unmounting device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:228
+#, c-format
+msgid ""
+"The device \"%s\" is being unmounted by the system. Please do not remove the "
+"media or disconnect the drive."
+msgstr ""
+
+#. not read-only, writing back data
+#: ../exo-mount-notify/main.c:235
+msgid "Writing data to device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:236
+#, c-format
+msgid ""
+"There is data that needs to be written to the device \"%s\" before it can be "
+"removed. Please do not remove the media or disconnect the drive."
+msgstr ""
+
 #: ../exo-open/main.c:59
 msgid "Usage: exo-open [URLs...]"
 msgstr "Použití: exo-open [AdresyURL...]"
@@ -1153,6 +1316,9 @@
 msgid "Failed to open URL \"%s\"."
 msgstr "Nepodařilo se otevřít adresu URL \"%s\"."
 
+#~ msgid "Failed to open display: %s"
+#~ msgstr "Nepodařilo se otevřít displej: %s"
+
 #~ msgid "Select an Icon"
 #~ msgstr "Vyberte si ikonu"
 

Modified: libexo/trunk/po/cy.po
===================================================================
--- libexo/trunk/po/cy.po	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/po/cy.po	2007-01-06 18:09:04 UTC (rev 24275)
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: cy\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-01-03 13:02+0100\n"
+"POT-Creation-Date: 2007-01-06 18:44+0100\n"
 "PO-Revision-Date: 2006-11-02 18:35+0000\n"
 "Last-Translator: Geraint Rowlands <ansbaradigeidfran at gmail.com>\n"
 "Language-Team: Welsh <xfce-i18n at xfce.org>\n"
@@ -41,7 +41,8 @@
 msgid "The size of the icon to render in pixels."
 msgstr "Maint yr eicon i'w lunio mewn picselau"
 
-#: ../exo/exo-gdk-pixbuf-extensions.c:770
+#: ../exo/exo-gdk-pixbuf-extensions.c:770 ../exo-mount/exo-mount-fstab.c:146
+#: ../exo-mount/exo-mount-fstab.c:187
 #, c-format
 msgid "Failed to open file \"%s\": %s"
 msgstr "Methwyd agor ffeil\"%s\": %s"
@@ -508,6 +509,7 @@
 msgstr "  --build-list      Dadansoddi parau (enw, ffeil)\n"
 
 #: ../exo-csource/main.c:248 ../exo-desktop-item-edit/main.c:153
+#: ../exo-mount/main.c:120 ../exo-mount-notify/main.c:164
 #: ../exo-open/main.c:129
 #, fuzzy, c-format
 msgid ""
@@ -524,6 +526,7 @@
 "\n"
 
 #: ../exo-csource/main.c:252 ../exo-desktop-item-edit/main.c:157
+#: ../exo-mount/main.c:124 ../exo-mount-notify/main.c:168
 #: ../exo-open/main.c:133
 #, c-format
 msgid ""
@@ -539,6 +542,7 @@
 "mhecyn tardd %s\n"
 
 #: ../exo-csource/main.c:256 ../exo-desktop-item-edit/main.c:161
+#: ../exo-mount/main.c:128 ../exo-mount-notify/main.c:172
 #: ../exo-open/main.c:137
 #, c-format
 msgid "Please report bugs to <%s>.\n"
@@ -698,7 +702,8 @@
 msgid "Preset icon when creating a desktop file"
 msgstr "Eicon rhagosodedig ar gyfer ffeil penbwrdd"
 
-#: ../exo-desktop-item-edit/main.c:79
+#: ../exo-desktop-item-edit/main.c:79 ../exo-mount/main.c:72
+#: ../exo-mount-notify/main.c:77
 msgid "Print version information and exit"
 msgstr "Argraffu gwybodaeth fersion a gorffen"
 
@@ -707,9 +712,10 @@
 msgid "[FILE|FOLDER]"
 msgstr "[FFEIL|PLYGELL]"
 
-#: ../exo-desktop-item-edit/main.c:138
-#, c-format
-msgid "Failed to open display: %s"
+#: ../exo-desktop-item-edit/main.c:138 ../exo-mount/main.c:106
+#: ../exo-mount-notify/main.c:150
+#, fuzzy
+msgid "Failed to open display"
 msgstr "Methwyd agor sgrïn: %s"
 
 #: ../exo-desktop-item-edit/main.c:168
@@ -1053,6 +1059,163 @@
 msgid "X Terminal"
 msgstr "Terfynell X"
 
+#: ../exo-mount/exo-mount-fstab.c:112
+msgid "Unknown error"
+msgstr ""
+
+#. generate an appropriate error message
+#. tell the caller that no matching device was found
+#: ../exo-mount/exo-mount-fstab.c:248 ../exo-mount/exo-mount-hal.c:339
+#, c-format
+msgid "Device \"%s\" not found in file system device table"
+msgstr ""
+
+#. definitely not a device that we're able to mount, eject or unmount
+#: ../exo-mount/exo-mount-hal.c:193 ../exo-mount/exo-mount-hal.c:246
+#, c-format
+msgid "Given device \"%s\" is not a volume or drive"
+msgstr ""
+
+#. TRANSLATORS: The user tried to eject a device although he's not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:616
+#, c-format
+msgid "You are not privileged to eject the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: An application is blocking a mounted volume from being ejected.
+#: ../exo-mount/exo-mount-hal.c:621
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being ejected"
+msgstr ""
+
+#. TRANSLATORS: User tried to mount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:846
+#, c-format
+msgid "You are not privileged to mount the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: User tried to unmount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:935
+#, c-format
+msgid "You are not privileged to unmount the volume \"%s\""
+msgstr ""
+
+#. TRANSLATORS: An application is blocking a volume from being unmounted.
+#: ../exo-mount/exo-mount-hal.c:940
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being unmounted"
+msgstr ""
+
+#. TRANSLATORS: HAL can only unmount volumes that were mounted via HAL.
+#: ../exo-mount/exo-mount-hal.c:945
+#, c-format
+msgid "The volume \"%s\" was probably mounted manually on the command line"
+msgstr ""
+
+#: ../exo-mount/main.c:63
+msgid "Eject rather than mount"
+msgstr ""
+
+#: ../exo-mount/main.c:64
+msgid "Unmount rather than mount"
+msgstr ""
+
+#: ../exo-mount/main.c:66
+msgid "Mount by HAL device UDI"
+msgstr ""
+
+#: ../exo-mount/main.c:68
+msgid "Mount by HAL device UDI (not supported)"
+msgstr ""
+
+#: ../exo-mount/main.c:70
+msgid "Mount by device file"
+msgstr ""
+
+#: ../exo-mount/main.c:71
+msgid "Don't show any dialogs"
+msgstr ""
+
+#. the caller must specify either a HAL UDI or a device file
+#: ../exo-mount/main.c:136
+msgid "Must specify HAL device UDI or device file"
+msgstr ""
+
+#. the caller must specify EITHER a HAL UDI or a device file
+#: ../exo-mount/main.c:144
+msgid "Must not specify both a HAL device UDI and a device file simultaneously"
+msgstr ""
+
+#: ../exo-mount/main.c:152
+msgid ""
+"Cannot mount by HAL device UDI, because HAL support was disabled for this "
+"build"
+msgstr ""
+
+#. the caller must not specify both eject and unmount
+#: ../exo-mount/main.c:167
+msgid "Cannot eject and unmount simultaneously"
+msgstr ""
+
+#: ../exo-mount/main.c:306
+#, fuzzy, c-format
+msgid "Failed to eject \"%s\""
+msgstr "Methu creu \"%s\"."
+
+#: ../exo-mount/main.c:308
+#, fuzzy, c-format
+msgid "Failed to unmount \"%s\""
+msgstr "Methu agor \"%s\""
+
+#: ../exo-mount/main.c:310
+#, fuzzy, c-format
+msgid "Failed to mount \"%s\""
+msgstr "Methu agor \"%s\""
+
+#. tell the user that the device can be removed now
+#: ../exo-mount-notify/main.c:111
+#, c-format
+msgid "The device \"%s\" is now safe to remove."
+msgstr ""
+
+#: ../exo-mount-notify/main.c:112
+msgid "Device is now safe to remove"
+msgstr ""
+
+#. read-only, just ejecting
+#: ../exo-mount-notify/main.c:221
+msgid "Ejecting device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:222
+#, c-format
+msgid "The device \"%s\" is being ejected. This may take some time."
+msgstr ""
+
+#. read-only, just unmounting
+#: ../exo-mount-notify/main.c:227
+msgid "Unmounting device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:228
+#, c-format
+msgid ""
+"The device \"%s\" is being unmounted by the system. Please do not remove the "
+"media or disconnect the drive."
+msgstr ""
+
+#. not read-only, writing back data
+#: ../exo-mount-notify/main.c:235
+msgid "Writing data to device"
+msgstr ""
+
+#: ../exo-mount-notify/main.c:236
+#, c-format
+msgid ""
+"There is data that needs to be written to the device \"%s\" before it can be "
+"removed. Please do not remove the media or disconnect the drive."
+msgstr ""
+
 #: ../exo-open/main.c:59
 msgid "Usage: exo-open [URLs...]"
 msgstr "Defnydd: exo-open [URLau...]"
@@ -1134,3 +1297,6 @@
 #, c-format
 msgid "Failed to open URL \"%s\"."
 msgstr "Methu agor URL \"%s\"."
+
+#~ msgid "Failed to open display: %s"
+#~ msgstr "Methwyd agor sgrïn: %s"

Modified: libexo/trunk/po/de.po
===================================================================
--- libexo/trunk/po/de.po	2007-01-05 22:11:48 UTC (rev 24274)
+++ libexo/trunk/po/de.po	2007-01-06 18:09:04 UTC (rev 24275)
@@ -8,8 +8,8 @@
 msgstr ""
 "Project-Id-Version: exo 0.3.1.13svn\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-01-03 13:02+0100\n"
-"PO-Revision-Date:  2007-01-03 13:02+0100\n"
+"POT-Creation-Date: 2007-01-06 18:44+0100\n"
+"PO-Revision-Date:  2007-01-06 18:02+0100\n"
 "Last-Translator: Fabian Nowak <timystery at arcor.de>\n"
 "Language-Team: German <de at li.org>\n"
 "MIME-Version: 1.0\n"
@@ -42,7 +42,8 @@
 msgid "The size of the icon to render in pixels."
 msgstr "Die Größe in der das Symbol gezeichnet werden soll."
 
-#: ../exo/exo-gdk-pixbuf-extensions.c:770
+#: ../exo/exo-gdk-pixbuf-extensions.c:770 ../exo-mount/exo-mount-fstab.c:146
+#: ../exo-mount/exo-mount-fstab.c:187
 #, c-format
 msgid "Failed to open file \"%s\": %s"
 msgstr "Konnte »%s« nicht öffnen: %s"
@@ -514,6 +515,7 @@
 msgstr "  --build-list      (Name, Datei) Paare parsen\n"
 
 #: ../exo-csource/main.c:248 ../exo-desktop-item-edit/main.c:153
+#: ../exo-mount/main.c:120 ../exo-mount-notify/main.c:164
 #: ../exo-open/main.c:129
 #, c-format
 msgid ""
@@ -530,6 +532,7 @@
 "\n"
 
 #: ../exo-csource/main.c:252 ../exo-desktop-item-edit/main.c:157
+#: ../exo-mount/main.c:124 ../exo-mount-notify/main.c:168
 #: ../exo-open/main.c:133
 #, c-format
 msgid ""
@@ -546,6 +549,7 @@
 "\n"
 
 #: ../exo-csource/main.c:256 ../exo-desktop-item-edit/main.c:161
+#: ../exo-mount/main.c:128 ../exo-mount-notify/main.c:172
 #: ../exo-open/main.c:137
 #, c-format
 msgid "Please report bugs to <%s>.\n"
@@ -707,7 +711,8 @@
 msgid "Preset icon when creating a desktop file"
 msgstr "Voreingestelltes Symbol"
 
-#: ../exo-desktop-item-edit/main.c:79
+#: ../exo-desktop-item-edit/main.c:79 ../exo-mount/main.c:72
+#: ../exo-mount-notify/main.c:77
 msgid "Print version information and exit"
 msgstr "Programmversion anzeigen und beenden"
 
@@ -716,10 +721,10 @@
 msgid "[FILE|FOLDER]"
 msgstr "[DATEI|ORDNER]"
 
-#: ../exo-desktop-item-edit/main.c:138
-#, c-format
-msgid "Failed to open display: %s"
-msgstr "Konnte Display nicht öffnen: %s"
+#: ../exo-desktop-item-edit/main.c:138 ../exo-mount/main.c:106
+#: ../exo-mount-notify/main.c:150
+msgid "Failed to open display"
+msgstr "Konnte Display nicht öffnen"
 
 #: ../exo-desktop-item-edit/main.c:168
 msgid "No file/folder specified"
@@ -1065,6 +1070,177 @@
 msgid "X Terminal"
 msgstr "X Terminal"
 
+#: ../exo-mount/exo-mount-fstab.c:112
+msgid "Unknown error"
+msgstr "Unbekannter Fehler"
+
+#. generate an appropriate error message
+#. tell the caller that no matching device was found
+#: ../exo-mount/exo-mount-fstab.c:248 ../exo-mount/exo-mount-hal.c:339
+#, c-format
+msgid "Device \"%s\" not found in file system device table"
+msgstr "Das Gerät »%s« ist nicht in der Datenträgertabelle enthalten"
+
+#. definitely not a device that we're able to mount, eject or unmount
+#: ../exo-mount/exo-mount-hal.c:193 ../exo-mount/exo-mount-hal.c:246
+#, c-format
+msgid "Given device \"%s\" is not a volume or drive"
+msgstr "Das Gerät »%s« ist kein gültiger Datenträger"
+
+#. TRANSLATORS: The user tried to eject a device although he's not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:616
+#, c-format
+msgid "You are not privileged to eject the volume \"%s\""
+msgstr "Sie sind nicht priviligiert den Datenträger »%s« auszuwerfen"
+
+#. TRANSLATORS: An application is blocking a mounted volume from being ejected.
+#: ../exo-mount/exo-mount-hal.c:621
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being ejected"
+msgstr ""
+"Eine Anwendung verhindert, dass der Datenträger »%s« ausgeworfen werden kann"
+
+#. TRANSLATORS: User tried to mount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:846
+#, c-format
+msgid "You are not privileged to mount the volume \"%s\""
+msgstr "Sie sind nicht priviligiert den Datenträger »%s« einzubinden"
+
+#. TRANSLATORS: User tried to unmount a volume, but is not privileged to do so.
+#: ../exo-mount/exo-mount-hal.c:935
+#, c-format
+msgid "You are not privileged to unmount the volume \"%s\""
+msgstr "Sie sind nicht priviligiert den Datenträger »%s« auszulösen"
+
+#. TRANSLATORS: An application is blocking a volume from being unmounted.
+#: ../exo-mount/exo-mount-hal.c:940
+#, c-format
+msgid "An application is preventing the volume \"%s\" from being unmounted"
+msgstr ""
+"Eine Anwendung verhindert