Index: src/plparse/totem-disc.c
===================================================================
--- src/plparse/totem-disc.c	(revision 3836)
+++ src/plparse/totem-disc.c	(working copy)
@@ -78,69 +78,106 @@
  * Resolve relative paths
  */
 
-static char *
-totem_disc_resolve_link (const char *dev, const char *buf)
+/* Copied from gtk+/gtk/gtkfilesystemunix.c */
+
+/* If this was a publically exported function, it should return
+ * a dup'ed result, but we make it modify-in-place for efficiency
+ * here, and because it works for us.
+ */
+static void
+canonicalize_filename (gchar *filename)
 {
-  char *parent, *new, *result;
+  gchar *p, *q;
+  gboolean last_was_slash = FALSE;
 
-  /* is it an absolute path? */
-  if (g_path_is_absolute (buf) != FALSE) {
-    result = realpath (buf, NULL);
-    if (result == NULL)
-      result = g_strdup (buf);
-  } else {
-    parent = g_path_get_dirname (dev);
-    new = g_build_filename (parent, buf, NULL);
-    result = realpath (new, NULL);
-    if (result == NULL)
-      result = g_strdup (new);
-    g_free (new);
-    g_free (parent);
-  }
+  p = filename;
+  q = filename;
 
-  return result;
-}
+  while (*p)
+    {
+      if (*p == G_DIR_SEPARATOR)
+	{
+	  if (!last_was_slash)
+	    *q++ = G_DIR_SEPARATOR;
 
-/*
- * So, devices can be symlinks and that screws up.
- */
+	  last_was_slash = TRUE;
+	}
+      else
+	{
+	  if (last_was_slash && *p == '.')
+	    {
+	      if (*(p + 1) == G_DIR_SEPARATOR ||
+		  *(p + 1) == '\0')
+		{
+		  if (*(p + 1) == '\0')
+		    break;
 
-static char *
-get_device (const char *device,
-	    GError     **error)
-{
-  char *buf;
-  char *dev = g_strdup (device);
-  struct stat st;
+		  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--;
+		    }
 
-  while (1) {
-    char *new;
+		  if (*(p + 2) == '\0')
+		    break;
 
-    if (lstat (dev, &st) != 0) {
-      g_set_error (error, 0, 0,
-          _("Failed to find real device node for %s: %s"),
-          dev, g_strerror (errno));
-      g_free (dev);
-      return NULL;
+		  p += 2;
+		}
+	      else
+		{
+		  *q++ = *p;
+		  last_was_slash = FALSE;
+		}
+	    }
+	  else
+	    {
+	      *q++ = *p;
+	      last_was_slash = FALSE;
+	    }
+	}
+
+      p++;
     }
 
-    if (!S_ISLNK (st.st_mode))
-      break;
+  if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
+    q--;
 
-    if (!(buf = g_file_read_link (dev, NULL))) {
-      g_set_error (error, 0, 0,
-          _("Failed to read symbolic link %s: %s"),
-          dev, g_strerror (errno));
-      g_free (dev);
+  *q = '\0';
+}
+
+static char *
+totem_resolve_symlink (const char *device, GError **error)
+{
+  char *dir, *link;
+  char *f;
+  char *f1;
+
+  f = g_strdup (device);
+  while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) {
+    link = g_file_read_link (f, error);
+    if(link == NULL) {
+      g_free (f);
       return NULL;
     }
-    new = totem_disc_resolve_link (dev, buf);
-    g_free (dev);
-    g_free (buf);
-    dev = new;
+
+    dir = g_path_get_dirname (f);
+    f1 = g_build_filename (dir, link, NULL);
+    g_free (dir);
+    g_free (f);
+    f = f1;
   }
 
-  return dev;
+  if (f != NULL)
+    canonicalize_filename (f);
+  return f;
 }
 
 static gboolean
@@ -160,7 +197,7 @@
     volume = list->data;
     if (!(pdev = gnome_vfs_volume_get_device_path (volume)))
       continue;
-    pdev2 = get_device (pdev, NULL);
+    pdev2 = totem_resolve_symlink (pdev, NULL);
     if (!pdev2) {
       g_free (pdev);
       continue;
@@ -211,7 +248,7 @@
     drive = list->data;
     if (!(pdev = gnome_vfs_drive_get_device_path (drive)))
       continue;
-    pdev2 = get_device (pdev, NULL);
+    pdev2 = totem_resolve_symlink (pdev, NULL);
     if (!pdev2) {
       g_free (pdev);
       continue;
@@ -309,7 +346,7 @@
   }
 
   /* retrieve mountpoint from gnome-vfs volumes and drives */
-  device = get_device (local, error);
+  device = totem_resolve_symlink (local, error);
   g_free (local);
   if (!device)
     return NULL;
