Am Freitag, den 12.06.2009, 01:25 +0200 schrieb Felix Zielcke:
> Am Freitag, den 12.06.2009, 01:21 +0200 schrieb Felix Zielcke:
> > 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
> 
> args just noticed I forgot the *free_ptr = buf2;
> I'm too lazy now to send an extra patch just for this.

Ok here's a new one which compiles without warnings.
-- 
Felix Zielcke
2009-06-12  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..5c648a1 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, char **free_ptr);
 
 #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/util/hostdisk.c b/util/hostdisk.c
index 1844a7e..25d01b2 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,97 @@ 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, char **free_ptr)
+{
+  struct stat st;
+  char *buf, *buf2;
+  uintptr_t offset = 0;
+  dev_t num;
+  size_t len;
+  char *p;
+#ifndef HAVE_REALPATH
+  size_t len2;
+#endif
+
+
+#ifdef HAVE_REALPATH
+  p = realpath (path, NULL);
+
+  if (p == NULL && errno != EINVAL)
+    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/";
+# 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..395db9d 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