udiskslinuxdrive.h udiskslinuxdrive.c \
udiskslinuxdriveata.h udiskslinuxdriveata.c \
udiskslinuxmanager.h udiskslinuxmanager.c \
+ udiskslinuxfsinfo.h udiskslinuxfsinfo.c \
udisksbasejob.h udisksbasejob.c \
udisksspawnedjob.h udisksspawnedjob.c \
udisksthreadedjob.h udisksthreadedjob.c \
#include "udiskslogging.h"
#include "udiskslinuxfilesystem.h"
#include "udiskslinuxblockobject.h"
+#include "udiskslinuxfsinfo.h"
#include "udisksdaemon.h"
#include "udiskscleanup.h"
#include "udisksdaemonutil.h"
return (char **) g_ptr_array_free (options, FALSE);
}
+static gchar *
+subst_str (const gchar *str,
+ const gchar *from,
+ const gchar *to)
+{
+ gchar **parts;
+ gchar *result;
+
+ parts = g_strsplit (str, from, 0);
+ result = g_strjoinv (to, parts);
+ g_strfreev (parts);
+ return result;
+}
+
/* ---------------------------------------------------------------------------------------------------- */
/*
UDisksDaemon *daemon;
const gchar *probed_fs_usage;
const gchar *probed_fs_type;
- gboolean supports_online;
+ const FSInfo *fs_info;
UDisksBaseJob *job;
gchar *escaped_label;
const gchar *action_id;
+ gchar *command;
+ gchar *tmp;
object = NULL;
daemon = NULL;
- supports_online = FALSE;
escaped_label = NULL;
+ command = NULL;
object = UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (filesystem)));
daemon = udisks_linux_block_object_get_daemon (UDISKS_LINUX_BLOCK_OBJECT (object));
probed_fs_usage = udisks_block_get_id_usage (block);
probed_fs_type = udisks_block_get_id_type (block);
- /* TODO: add support for other fstypes */
- if (!(g_strcmp0 (probed_fs_usage, "filesystem") == 0 &&
- (g_strcmp0 (probed_fs_type, "ext2") == 0 ||
- g_strcmp0 (probed_fs_type, "ext3") == 0 ||
- g_strcmp0 (probed_fs_type, "ext4") == 0)))
+ if (g_strcmp0 (probed_fs_usage, "filesystem") != 0)
+ {
+ g_dbus_method_invocation_return_error (invocation,
+ UDISKS_ERROR,
+ UDISKS_ERROR_NOT_SUPPORTED,
+ "Cannot change label on device of type %s",
+ probed_fs_usage);
+ goto out;
+ }
+
+ fs_info = get_fs_info (probed_fs_type);
+
+ if (fs_info == NULL || fs_info->command_change_label == NULL)
{
g_dbus_method_invocation_return_error (invocation,
UDISKS_ERROR,
probed_fs_type);
goto out;
}
- supports_online = TRUE;
+
+ /* VFAT does not allow some characters; as mlabel hangs with interactive
+ * question in this case, check in advance */
+ if (g_strcmp0 (probed_fs_type, "vfat") == 0)
+ {
+ for (tmp = "\"*/:<>?\\|"; *tmp; ++tmp)
+ {
+ if (strchr (label, *tmp) != NULL)
+ {
+ g_dbus_method_invocation_return_error (invocation,
+ UDISKS_ERROR,
+ UDISKS_ERROR_NOT_SUPPORTED,
+ "character '%c' not supported in VFAT labels",
+ *tmp);
+ goto out;
+ }
+ }
+ }
/* Fail if the device is already mounted and the tools/drivers doesn't
* support changing the label in that case
*/
- if (filesystem != NULL && !supports_online)
+ if (filesystem != NULL && !fs_info->supports_online_label_rename)
{
const gchar * const *existing_mount_points;
existing_mount_points = udisks_filesystem_get_mount_points (filesystem);
goto out;
escaped_label = g_shell_quote (label);
+
+ if (fs_info->command_clear_label != NULL && strlen (label) == 0)
+ {
+ command = subst_str (fs_info->command_clear_label, "$DEVICE", udisks_block_get_device (block));
+ }
+ else
+ {
+ tmp = subst_str (fs_info->command_change_label, "$DEVICE", udisks_block_get_device (block));
+ command = subst_str (tmp, "$LABEL", escaped_label);
+ g_free (tmp);
+ }
+
job = udisks_daemon_launch_spawned_job (daemon,
NULL, /* cancellable */
0, /* uid_t run_as_uid */
0, /* uid_t run_as_euid */
NULL, /* input_string */
- "e2label %s %s",
- udisks_block_get_device (block),
- escaped_label);
+ "%s", command);
g_signal_connect (job,
"completed",
G_CALLBACK (on_set_label_job_completed),
out:
g_free (escaped_label);
+ g_free (command);
return TRUE; /* returning TRUE means that we handled the method invocation */
}
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Martin Pitt <martin.pitt@ubuntu.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <string.h>
+#include <glib.h>
+
+#include "config.h"
+#include "udiskslinuxfsinfo.h"
+
+const FSInfo _fs_info[] =
+ {
+ {
+ "ext2",
+ "e2label $DEVICE $LABEL",
+ NULL,
+ TRUE,
+ },
+ {
+ "ext3",
+ "e2label $DEVICE $LABEL",
+ NULL,
+ TRUE,
+ },
+ {
+ "ext4",
+ "e2label $DEVICE $LABEL",
+ NULL,
+ TRUE,
+ },
+ {
+ "vfat",
+ "mlabel -i $DEVICE ::$LABEL",
+ "mlabel -i $DEVICE -c ::",
+ FALSE,
+ },
+ {
+ "ntfs",
+ "ntfslabel $DEVICE $LABEL",
+ NULL,
+ FALSE,
+ },
+ {
+ "xfs",
+ "xfs_admin -L $LABEL $DEVICE",
+ "xfs_admin -L -- $DEVICE",
+ FALSE,
+ },
+ {
+ "reiserfs",
+ "reiserfstune -l $LABEL $DEVICE",
+ NULL,
+ FALSE,
+ },
+ {
+ "nilfs2",
+ "nilfs-tune -L $LABEL $DEVICE",
+ NULL,
+ FALSE,
+ },
+ {
+ "btrfs",
+ NULL,
+ NULL,
+ FALSE,
+ },
+ {
+ "minix",
+ NULL,
+ NULL,
+ FALSE,
+ },
+ {
+ "swap",
+ NULL,
+ NULL,
+ FALSE,
+ },
+ };
+
+/**
+ * get_fs_info:
+ *
+ * Look up #FSInfo record for a particular file system.
+ * @fstype: file system type name
+ *
+ * Returns: (transfer none): #FSInfo struct for @fstype, or %NULL if that file
+ * system is unknown. Do not free or modify.
+ */
+const FSInfo *
+get_fs_info (const gchar *fstype)
+{
+ gint n;
+ g_return_val_if_fail (fstype != NULL, NULL);
+
+ for (n = 0; n < sizeof(_fs_info)/sizeof(FSInfo); n++)
+ {
+ if (strcmp (_fs_info[n].fstype, fstype) == 0)
+ return &_fs_info[n];
+ }
+
+ return NULL;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Martin Pitt <martin.pitt@ubuntu.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __UDISKS_LINUX_FSINFO_H__
+#define __UDISKS_LINUX_FSINFO_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ const gchar *fstype;
+ const gchar *command_change_label; /* should have $DEVICE and $LABEL */
+ const gchar *command_clear_label; /* should have $DEVICE; if NULL, call command_change_label with $LABEL == '' */
+ gboolean supports_online_label_rename;
+} FSInfo;
+
+const FSInfo *get_fs_info (const gchar *fstype);
+
+G_END_DECLS
+
+#endif /* __UDISKS_LINUX_FSINFO_H__ */