Am Donnerstag, den 11.06.2009, 01:00 +0200 schrieb Felix Zielcke:
> Am Dienstag, den 09.06.2009, 23:51 +0200 schrieb Vladimir 'phcoder'
> Serbinenko:
> 
> > +
> > +char *grub_make_system_path_relative_to_its_root (char *path)
> > +{
> > +
> > +  struct stat st;
> > +  char buf[500], buf2[500];
> > Use malloc instead of static allocation
> 
> Changed.
> 
> > +      p = strrchr (buf, '/');
> > +      if (p != buf)
> > +   *p = 0;
> > +      else *++p = 0;
> > You assume path starts with /. You have to check this. Otherwise you
> > may get sigsegv
> 
> Changed.
> > +      strcpy(buf2,buf);
> > Just save (p - buf) instead of copying buf to buf2
> 
> I did this now if realpath () isn't avaible.
> Now realpath is used in case it's avaible. POSIX specifies it and
> readlink is actually using it if it's avaible. I didn't read the source
> correctly.
> The problem is just Cygwin. It has it but it returns the cygwin path.
> So C:\\Windows would get /cygdrive/c/windows, which is easy to handle.
> But realpath ("/boot/grub") would return /boot/grub which isn't true
> from Windows/GRUB point of view.
> Maybe Christian and Bean can say something about it.
> MingW doestn't have it and I don't know what Windows would have, so the
> MingW users would still use my own way.

Here's now a new one which aborts if realpath is avaible but doestn't
support (path, NULL)
and the fallback function is changed to dynamically allocate the memory.
And now all memory is properly free'd
-- 
Felix Zielcke
2009-06-11  Felix Zielcke  <fziel...@z-51.de>

        * configure.ac (AC_CHECK_FUNCS): Add realpath.
        * include/grub/util/hostdisk.c
        (grub_make_system_path_relative_to_its_root): New function
        prototype.
        * util/hostdisk.c: Include <stdint.h>.
        (grub_make_system_path_relative_to_its_root): New function.
        * util/i386/pc/grub-setup.c (setup): Use
        grub_make_system_path_relative_to_its_root to make core_path_dev
        relative to the partition.

diff --git a/configure.ac b/configure.ac
index b0f7bb7..9d594db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -196,7 +196,7 @@ if test "$target_cpu"-"$platform" = i386-pc; then
 fi
 
 # Check for functions.
-AC_CHECK_FUNCS(posix_memalign memalign asprintf)
+AC_CHECK_FUNCS(posix_memalign memalign asprintf realpath)
 
 #
 # Check for target programs.
diff --git a/include/grub/util/hostdisk.h b/include/grub/util/hostdisk.h
index 21efb0d..85df1c6 100644
--- a/include/grub/util/hostdisk.h
+++ b/include/grub/util/hostdisk.h
@@ -23,5 +23,6 @@
 void grub_util_biosdisk_init (const char *dev_map);
 void grub_util_biosdisk_fini (void);
 char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
+char *grub_make_system_path_relative_to_its_root (char *path,void **free_ptr);
 
 #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/util/hostdisk.c b/util/hostdisk.c
index 1844a7e..3224e07 100644
--- a/util/hostdisk.c
+++ b/util/hostdisk.c
@@ -27,6 +27,7 @@
 #include <grub/misc.h>
 
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -1076,3 +1077,95 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
   return make_device_name (drive, -1, -1);
 #endif
 }
+
+char *
+grub_make_system_path_relative_to_its_root (char *path, void **free_ptr)
+{
+  struct stat st;
+  char *buf, *buf2;
+  uintptr_t offset = 0;
+  dev_t num;
+  long path_max;
+  size_t len, len2;
+  char *p;
+
+
+#ifdef HAVE_REALPATH
+  p = realpath (path, NULL);
+
+  if (p == NULL) && (ernno != )
+    grub_util_error ("failed to get realpath of %s", path);
+  else
+    grub_util_error ("realpath not supporting (path, NULL)");
+  len = strlen (p) + 1;
+  buf = xmalloc (len);
+  buf2 = xmalloc (len);
+# ifdef __CYGWIN__
+  if (strncmp (p, 10, "/cygdrive/") == 0)
+    strcpy (buf, p + sizeof ("/cygdrive/c") - 1);
+  else
+    grub_util_error "path not under /cygdrive/. Aborting.";
+# else
+  strcpy (buf, p);
+#endif
+  free (p);
+#else /* ! HAVE_REALPATH */
+# warning "The function `grub_make_system_path_relative_to_its_root' might not 
work on your OS correctly."
+  if (*path != '/')
+    {
+      len2 = 4096;
+      do
+       {
+         p = getcwd (buf, len)
+           if (p == NULL)
+             {
+               if (errno != ERANGE)
+                 grub_util_error ("can not get current working directory");
+               else
+                 len2 *= 2;
+             }
+       } while (p == NULL)
+
+      buf = xmalloc (strlen (path) + len2 + 1);
+      strcat (buf, "/");
+      strcat (buf, path);
+    }
+  else
+    {
+      buf = xmalloc (strlen (path) + 1);
+      strcpy (buf, path)
+    }
+#endif /* ! HAVE_REALPATH */
+  buf2 = xmalloc (strlen (buf) + 1);
+  strcpy (buf2, buf);
+  *free_ptr = buf2;
+  if (stat (buf, &st) < 0)
+    grub_util_error ("can not stat %s", p);
+
+  num = st.st_dev;
+  while (1)
+    {
+      p = strrchr (buf, '/');
+      if (p == NULL)
+       grub_util_error ("FIXME no / in buf");
+      if (p != buf)
+       *p = 0;
+      else
+       *++p = 0;
+
+      if (stat (buf, &st) < 0)
+       grub_util_error ("can not stat %s", buf);
+
+      if (st.st_dev != num)
+       break;
+
+      offset = p - buf;
+      if (offset == 1)
+       {
+         free (buf);
+         return buf2;
+       }
+    }
+  free (buf);
+  return buf2 + offset;
+}
diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c
index bdf234c..c9243bd 100644
--- a/util/i386/pc/grub-setup.c
+++ b/util/i386/pc/grub-setup.c
@@ -89,7 +89,7 @@ setup (const char *dir,
        const char *root, const char *dest, int must_embed, int force)
 {
   char *boot_path, *core_path, *core_path_dev;
-  char *boot_img, *core_img;
+  char *boot_img, *core_img, *p, *free_ptr;
   size_t boot_size, core_size;
   grub_uint16_t core_sectors;
   grub_device_t root_dev, dest_dev;
@@ -404,7 +404,10 @@ unable_to_embed:
 
   /* Make sure that GRUB reads the identical image as the OS.  */
   tmp_img = xmalloc (core_size);
-  core_path_dev = grub_util_get_path (dir, core_file);
+  p = grub_util_get_path (dir, core_file);
+  core_path_dev = grub_make_system_path_relative_to_its_root (p,&free_ptr);
+  free (p);
+  free (free_ptr);
 
   /* It is a Good Thing to sync two times.  */
   sync ();
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to