2009-11-24 Felix Zielcke <fzielcke@z-51.de>
* util/grub-mkrelpath.c: New file. * conf/common.rmk (bin_UTILITIES): Add grub-mkrelpath. (grub_mkrelpath_SOURCES): New variable. * include/grub/util/misc.h: New function prototype. * util/misc.c (make_system_path_relative_to_its_root): New function. * util/grub-mkconfig_lib.in (bindir): New variable. (grub_mkrelpath): Likewise. (make_system_path_relative_to_its_root): Use grub-mkrelpath. * util/probe.c (probe): Make the file path relative to its root. Change a info message to use the GRUB path. Enable again the check if we can read the file with GRUB facilities. * util/i386/pc/grub-setup.c (setup): Make core.img path relative to its root.
This commit is contained in:
commit
4501250b6c
8 changed files with 221 additions and 52 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2009-11-24 Felix Zielcke <fzielcke@z-51.de>
|
||||||
|
|
||||||
|
* util/grub-mkrelpath.c: New file.
|
||||||
|
* conf/common.rmk (bin_UTILITIES): Add grub-mkrelpath.
|
||||||
|
(grub_mkrelpath_SOURCES): New variable.
|
||||||
|
* include/grub/util/misc.h: New function prototype.
|
||||||
|
* util/misc.c (make_system_path_relative_to_its_root): New function.
|
||||||
|
|
||||||
|
* util/grub-mkconfig_lib.in (bindir): New variable.
|
||||||
|
(grub_mkrelpath): Likewise.
|
||||||
|
(make_system_path_relative_to_its_root): Use grub-mkrelpath.
|
||||||
|
|
||||||
|
* util/probe.c (probe): Make the file path relative to its root.
|
||||||
|
Change a info message to use the GRUB path. Enable again the
|
||||||
|
check if we can read the file with GRUB facilities.
|
||||||
|
|
||||||
|
* util/i386/pc/grub-setup.c (setup): Make core.img path relative
|
||||||
|
to its root.
|
||||||
|
|
||||||
2009-11-24 Felix Zielcke <fzielcke@z-51.de>
|
2009-11-24 Felix Zielcke <fzielcke@z-51.de>
|
||||||
|
|
||||||
* Makefile.in: Don't include GRUB_CONTRIB makefiles with emu
|
* Makefile.in: Don't include GRUB_CONTRIB makefiles with emu
|
||||||
|
|
|
@ -71,6 +71,10 @@ grub_mkfont_CFLAGS = $(freetype_cflags)
|
||||||
grub_mkfont_LDFLAGS = $(freetype_libs)
|
grub_mkfont_LDFLAGS = $(freetype_libs)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# For grub-mkrelpath.
|
||||||
|
bin_UTILITIES += grub-mkrelpath
|
||||||
|
grub_mkrelpath_SOURCES = util/grub-mkrelpath.c util/misc.c
|
||||||
|
|
||||||
# For the parser.
|
# For the parser.
|
||||||
grub_script.tab.c grub_script.tab.h: script/parser.y
|
grub_script.tab.c grub_script.tab.h: script/parser.y
|
||||||
$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
|
$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* GRUB -- GRand Unified Bootloader
|
* GRUB -- GRand Unified Bootloader
|
||||||
* Copyright (C) 2002,2003,2005,2006,2007,2008 Free Software Foundation, Inc.
|
* Copyright (C) 2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* GRUB is free software: you can redistribute it and/or modify
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -76,4 +76,7 @@ grub_int64_t grub_util_get_disk_size (char *name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char *make_system_path_relative_to_its_root (const char *path);
|
||||||
|
|
||||||
#endif /* ! GRUB_UTIL_MISC_HEADER */
|
#endif /* ! GRUB_UTIL_MISC_HEADER */
|
||||||
|
|
|
@ -20,10 +20,12 @@ prefix=@prefix@
|
||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
datarootdir=@datarootdir@
|
datarootdir=@datarootdir@
|
||||||
datadir=@datadir@
|
datadir=@datadir@
|
||||||
|
bindir=@bindir@
|
||||||
sbindir=@sbindir@
|
sbindir=@sbindir@
|
||||||
pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
|
pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
|
||||||
|
|
||||||
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
|
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
|
||||||
|
grub_mkrelpath=${bindir}/`echo grub-mkrelpath | sed ${transform}`
|
||||||
|
|
||||||
grub_warn ()
|
grub_warn ()
|
||||||
{
|
{
|
||||||
|
@ -32,49 +34,7 @@ grub_warn ()
|
||||||
|
|
||||||
make_system_path_relative_to_its_root ()
|
make_system_path_relative_to_its_root ()
|
||||||
{
|
{
|
||||||
path=$1
|
path="`${grub_mkrelpath} $1`"
|
||||||
# abort if file doesn't exist
|
|
||||||
if test -e $path ; then : ;else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# canonicalize
|
|
||||||
if path=`readlink -f $path` ; then : ; else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if not a directory, climb up to the directory containing it
|
|
||||||
if test -d $path ; then
|
|
||||||
dir=$path
|
|
||||||
else
|
|
||||||
dir=`echo $path | sed -e "s,/[^/]*$,,g"`
|
|
||||||
fi
|
|
||||||
|
|
||||||
num=`stat -c %d $dir`
|
|
||||||
|
|
||||||
# this loop sets $dir to the root directory of the filesystem we're inspecting
|
|
||||||
while : ; do
|
|
||||||
parent=`readlink -f $dir/..`
|
|
||||||
if [ "x`stat -c %d $parent`" = "x$num" ] ; then : ; else
|
|
||||||
# $parent is another filesystem; we found it.
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if [ "x$dir" = "x/" ] ; then
|
|
||||||
# / is our root.
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
dir=$parent
|
|
||||||
done
|
|
||||||
|
|
||||||
# This function never prints trailing slashes (so that its output can be
|
|
||||||
# appended a slash unconditionally). Each slash in $dir is considered a
|
|
||||||
# preceding slash, and therefore the root directory is an empty string.
|
|
||||||
if [ "$dir" = "/" ] ; then
|
|
||||||
dir=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# XXX: This fails if $dir contains ','.
|
|
||||||
path=`echo "$path" | sed -e "s,^$dir,,g"` || return 1
|
|
||||||
|
|
||||||
case "`uname 2>/dev/null`" in
|
case "`uname 2>/dev/null`" in
|
||||||
CYGWIN*)
|
CYGWIN*)
|
||||||
|
|
99
util/grub-mkrelpath.c
Normal file
99
util/grub-mkrelpath.c
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/* grub-mkrelpath.c - make a system path relative to its root */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/util/misc.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
static struct option options[] =
|
||||||
|
{
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"version", no_argument, 0, 'V'},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage (int status)
|
||||||
|
{
|
||||||
|
if (status)
|
||||||
|
fprintf (stderr, "Try ``grub-mkrelpath --help'' for more information.\n");
|
||||||
|
else
|
||||||
|
printf ("\
|
||||||
|
Usage: grub-mkrelpath [OPTIONS] PATH\n\
|
||||||
|
\n\
|
||||||
|
Make a system path relative to it's root.\n\
|
||||||
|
\n\
|
||||||
|
Options:\n\
|
||||||
|
-h, --help display this message and exit\n\
|
||||||
|
-V, --version print version information and exit\n\
|
||||||
|
\n\
|
||||||
|
Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
|
||||||
|
|
||||||
|
exit (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *argument, *relpath;
|
||||||
|
|
||||||
|
progname = "grub-mkrelpath";
|
||||||
|
|
||||||
|
/* Check for options. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int c = getopt_long (argc, argv, "hV", options, 0);
|
||||||
|
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
usage (0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
printf ("%s (%s) %s\n", progname, PACKAGE_NAME, PACKAGE_VERSION);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
usage (1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind >= argc)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "No path is specified.\n");
|
||||||
|
usage (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optind + 1 != argc)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind + 1]);
|
||||||
|
usage (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
argument = argv[optind];
|
||||||
|
|
||||||
|
relpath = make_system_path_relative_to_its_root (argument);
|
||||||
|
printf ("%s\n", relpath);
|
||||||
|
free (relpath);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -235,9 +235,6 @@ probe (const char *path, char *device_name)
|
||||||
|
|
||||||
if (print == PRINT_FS)
|
if (print == PRINT_FS)
|
||||||
{
|
{
|
||||||
/* FIXME: `path' can't be used to read a file via GRUB facilities,
|
|
||||||
because it's not relative to its root. */
|
|
||||||
#if 0
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
stat (path, &st);
|
stat (path, &st);
|
||||||
|
@ -247,12 +244,17 @@ probe (const char *path, char *device_name)
|
||||||
/* Regular file. Verify that we can read it properly. */
|
/* Regular file. Verify that we can read it properly. */
|
||||||
|
|
||||||
grub_file_t file;
|
grub_file_t file;
|
||||||
|
char *rel_path;
|
||||||
grub_util_info ("reading %s via OS facilities", path);
|
grub_util_info ("reading %s via OS facilities", path);
|
||||||
filebuf_via_sys = grub_util_read_image (path);
|
filebuf_via_sys = grub_util_read_image (path);
|
||||||
|
|
||||||
grub_util_info ("reading %s via GRUB facilities", path);
|
rel_path = make_system_path_relative_to_its_root (path);
|
||||||
asprintf (&grub_path, "(%s)%s", drive_name, path);
|
asprintf (&grub_path, "(%s)%s", drive_name, rel_path);
|
||||||
|
free (rel_path);
|
||||||
|
grub_util_info ("reading %s via GRUB facilities", grub_path);
|
||||||
file = grub_file_open (grub_path);
|
file = grub_file_open (grub_path);
|
||||||
|
if (! file)
|
||||||
|
grub_util_error ("can not open %s via GRUB facilities", grub_path);
|
||||||
filebuf_via_grub = xmalloc (file->size);
|
filebuf_via_grub = xmalloc (file->size);
|
||||||
grub_file_read (file, filebuf_via_grub, file->size);
|
grub_file_read (file, filebuf_via_grub, file->size);
|
||||||
|
|
||||||
|
@ -261,7 +263,6 @@ probe (const char *path, char *device_name)
|
||||||
if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
|
if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
|
||||||
grub_util_error ("files differ");
|
grub_util_error ("files differ");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
printf ("%s\n", fs->name);
|
printf ("%s\n", fs->name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ setup (const char *dir,
|
||||||
const char *boot_file, const char *core_file,
|
const char *boot_file, const char *core_file,
|
||||||
const char *root, const char *dest, int must_embed, int force, int fs_probe)
|
const char *root, const char *dest, int must_embed, int force, int fs_probe)
|
||||||
{
|
{
|
||||||
char *boot_path, *core_path, *core_path_dev;
|
char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
|
||||||
char *boot_img, *core_img;
|
char *boot_img, *core_img;
|
||||||
size_t boot_size, core_size;
|
size_t boot_size, core_size;
|
||||||
grub_uint16_t core_sectors;
|
grub_uint16_t core_sectors;
|
||||||
|
@ -426,7 +426,9 @@ unable_to_embed:
|
||||||
|
|
||||||
/* Make sure that GRUB reads the identical image as the OS. */
|
/* Make sure that GRUB reads the identical image as the OS. */
|
||||||
tmp_img = xmalloc (core_size);
|
tmp_img = xmalloc (core_size);
|
||||||
core_path_dev = grub_util_get_path (dir, core_file);
|
core_path_dev_full = grub_util_get_path (dir, core_file);
|
||||||
|
core_path_dev = make_system_path_relative_to_its_root (core_path_dev_full);
|
||||||
|
free (core_path_dev_full);
|
||||||
|
|
||||||
/* It is a Good Thing to sync two times. */
|
/* It is a Good Thing to sync two times. */
|
||||||
sync ();
|
sync ();
|
||||||
|
|
81
util/misc.c
81
util/misc.c
|
@ -18,10 +18,12 @@
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -447,3 +449,82 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __MINGW32__ */
|
#endif /* __MINGW32__ */
|
||||||
|
|
||||||
|
/* This function never prints trailing slashes (so that its output
|
||||||
|
can be appended a slash unconditionally). */
|
||||||
|
char *
|
||||||
|
make_system_path_relative_to_its_root (const char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
char *p, *buf, *buf2, *buf3;
|
||||||
|
uintptr_t offset = 0;
|
||||||
|
dev_t num;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* canonicalize. */
|
||||||
|
p = realpath (path, NULL);
|
||||||
|
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
if (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 = strdup (p);
|
||||||
|
free (p);
|
||||||
|
|
||||||
|
if (stat (buf, &st) < 0)
|
||||||
|
grub_util_error ("can not stat %s: %s", buf, strerror (errno));
|
||||||
|
|
||||||
|
buf2 = strdup (buf);
|
||||||
|
num = st.st_dev;
|
||||||
|
|
||||||
|
/* This loop sets offset to the number of chars of the root
|
||||||
|
directory we're inspecting. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
p = strrchr (buf, '/');
|
||||||
|
if (p == NULL)
|
||||||
|
/* This should never happen. */
|
||||||
|
grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)");
|
||||||
|
if (p != buf)
|
||||||
|
*p = 0;
|
||||||
|
else
|
||||||
|
*++p = 0;
|
||||||
|
|
||||||
|
if (stat (buf, &st) < 0)
|
||||||
|
grub_util_error ("can not stat %s: %s", buf, strerror (errno));
|
||||||
|
|
||||||
|
/* buf is another filesystem; we found it. */
|
||||||
|
if (st.st_dev != num)
|
||||||
|
break;
|
||||||
|
|
||||||
|
offset = p - buf;
|
||||||
|
/* offset == 1 means root directory. */
|
||||||
|
if (offset == 1)
|
||||||
|
{
|
||||||
|
free (buf);
|
||||||
|
len = strlen (buf2);
|
||||||
|
while (buf2[len - 1] == '/' && len > 1)
|
||||||
|
{
|
||||||
|
buf2[len - 1] = '\0';
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
return buf2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (buf);
|
||||||
|
buf3 = strdup (buf2 + offset);
|
||||||
|
free (buf2);
|
||||||
|
|
||||||
|
len = strlen (buf3);
|
||||||
|
while (buf3[len - 1] == '/' && len > 1)
|
||||||
|
{
|
||||||
|
buf3[len - 1] = '\0';
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf3;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue