All of lore.kernel.org
 help / color / mirror / Atom feed
From: Felix Zielcke <fzielcke@z-51.de>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: [PATCH] Re: grub-install --root-directory=/mnt /dev/sda1 fails
Date: Thu, 11 Jun 2009 01:00:21 +0200	[thread overview]
Message-ID: <1244674821.8525.23.camel@fz.local> (raw)
In-Reply-To: <d7ead6de0906091451i41e55a48udbce528698a82390@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1157 bytes --]

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.

-- 
Felix Zielcke

[-- Attachment #2: make_sys_path_relative.patch.3 --]
[-- Type: text/plain, Size: 4504 bytes --]

2009-06-11  Felix Zielcke  <fzielcke@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 e448c2f..9e923a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -205,7 +205,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..a1ecf59 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)
 
 #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
diff --git a/util/hostdisk.c b/util/hostdisk.c
index a7262dd..bce1b95 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,94 @@ 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)
+{
+  struct stat st;
+  char *buf, *buf2;
+  uintptr_t offset = 0;
+  dev_t num;
+  long path_max;
+#ifdef HAVE_REALPATH
+  char *p;
+#endif
+
+
+#ifdef HAVE_REALPATH
+# ifdef PATH_MAX
+  path_max = PATH_MAX
+# else
+  path_max = pathconf (path, _PC_PATH_MAX);
+  if (path_max <= 0)
+    /* 1024 is taken from glibc-2.10.  */
+    path_max = 1024;
+# endif
+  p = xmalloc (path_max);
+  p = realpath (path, p);
+  if (p == NULL)
+    grub_util_error ("failed to get realpath of %s", path);
+
+#ifdef __CYGWIN__
+  if (strncmp (p,"/cygdrive/") == 0)
+    {
+      p += sizeof "/cygdrive/c" - 1;
+    }
+  else
+    grub_util_error "path not under /cygdrive/ aborting.";
+#endif
+  buf = xmalloc (path_max);
+  buf2 = xmalloc (path_max);
+  strcpy (buf, p);
+  free (p);
+#else /* ! HAVE_REALPATH */
+# warning "The function `grub_make_system_path_relative_to_its_root' might not work on your OS correctly."
+  path_max = 1024;
+  buf = xmalloc (path_max);
+  buf2 = xmalloc (path_max);
+  memset (buf, 0, sizeof (buf));
+  if (*path != '/')
+    {
+      size_t len = strlen (path);
+
+      if (getcwd (buf, 1024 - len) == NULL)
+	grub_util_error ("can not get current working directory");
+
+      strcat (buf, "/");
+      strcat (buf, path);
+    }
+  else
+    {
+      if (strlen (path) > 1024)
+	grub_util_error ("path too long");
+      strncpy (buf, path, 1024);
+    }
+#endif /* ! HAVE_REALPATH */
+
+  strcpy (buf2, buf);
+  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 p");
+      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)
+	return buf2;
+    }
+  return buf2 + offset;
+}
diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c
index 997811b..7fb0273 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;
   size_t boot_size, core_size;
   grub_uint16_t core_sectors;
   grub_device_t root_dev, dest_dev;
@@ -404,7 +404,9 @@ 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 (p);
   
   /* It is a Good Thing to sync two times.  */
   sync ();

  reply	other threads:[~2009-06-10 23:00 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-06 14:31 grub-install --root-directory=/mnt /dev/sda1 fails Felix Zielcke
2009-05-06 15:12 ` Vladimir 'phcoder' Serbinenko
2009-06-01 19:39   ` Felix Zielcke
2009-06-08 21:20     ` [PATCH] " Felix Zielcke
2009-06-09 21:51       ` Vladimir 'phcoder' Serbinenko
2009-06-10 23:00         ` Felix Zielcke [this message]
2009-06-11 23:21           ` Felix Zielcke
2009-06-11 23:25             ` Felix Zielcke
2009-06-12 10:28               ` Felix Zielcke
2009-06-12 16:21                 ` Pavel Roskin
2009-06-12 16:33                   ` Felix Zielcke
2009-07-01 14:33     ` Felix Zielcke
2009-07-04 20:09       ` Robert Millan
2009-07-08 14:16         ` Felix Zielcke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1244674821.8525.23.camel@fz.local \
    --to=fzielcke@z-51.de \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.