Fix symlink handling on iso9660.
* grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink All users updated. (grub_iso9660_susp_iterate): Accept zero-size iterate. (grub_iso9660_read_symlink): Moved most of code ... (grub_iso9660_iterate_dir): ... here. Fill node->symlink.
This commit is contained in:
parent
db82136381
commit
66b4085033
2 changed files with 90 additions and 102 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2011-10-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fix symlink handling on iso9660.
|
||||||
|
|
||||||
|
* grub-core/fs/iso9660.c (grub_fshelp_node): Remove dir_off. Add symlink
|
||||||
|
All users updated.
|
||||||
|
(grub_iso9660_susp_iterate): Accept zero-size iterate.
|
||||||
|
(grub_iso9660_read_symlink): Moved most of code ...
|
||||||
|
(grub_iso9660_iterate_dir): ... here. Fill node->symlink.
|
||||||
|
|
||||||
2011-10-25 Vladimir Serbinenko <phcoder@gmail.com>
|
2011-10-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge):
|
* grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge):
|
||||||
|
|
|
@ -159,7 +159,7 @@ struct grub_fshelp_node
|
||||||
{
|
{
|
||||||
struct grub_iso9660_data *data;
|
struct grub_iso9660_data *data;
|
||||||
grub_size_t have_dirents, alloc_dirents;
|
grub_size_t have_dirents, alloc_dirents;
|
||||||
grub_off_t dir_off;
|
char *symlink;
|
||||||
struct grub_iso9660_dir dirents[8];
|
struct grub_iso9660_dir dirents[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf)
|
||||||
every entry. */
|
every entry. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
|
grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
|
||||||
grub_size_t sua_size,
|
grub_ssize_t sua_size,
|
||||||
grub_err_t (*hook)
|
grub_err_t (*hook)
|
||||||
(struct grub_iso9660_susp_entry *entry))
|
(struct grub_iso9660_susp_entry *entry))
|
||||||
{
|
{
|
||||||
|
@ -288,6 +288,9 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sua_size <= 0)
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
|
||||||
if (load_sua ())
|
if (load_sua ())
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
@ -454,7 +457,7 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
rootnode.data = data;
|
rootnode.data = data;
|
||||||
rootnode.alloc_dirents = 0;
|
rootnode.alloc_dirents = 0;
|
||||||
rootnode.have_dirents = 1;
|
rootnode.have_dirents = 1;
|
||||||
rootnode.dir_off = 0;
|
rootnode.symlink = 0;
|
||||||
rootnode.dirents[0] = data->voldesc.rootdir;
|
rootnode.dirents[0] = data->voldesc.rootdir;
|
||||||
|
|
||||||
/* The 2nd data byte stored how many bytes are skipped every time
|
/* The 2nd data byte stored how many bytes are skipped every time
|
||||||
|
@ -480,102 +483,7 @@ grub_iso9660_mount (grub_disk_t disk)
|
||||||
static char *
|
static char *
|
||||||
grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
grub_iso9660_read_symlink (grub_fshelp_node_t node)
|
||||||
{
|
{
|
||||||
int sua_off;
|
return node->symlink ? grub_strdup (node->symlink) : grub_strdup ("");
|
||||||
int sua_size;
|
|
||||||
char *symlink = 0;
|
|
||||||
int addslash = 0;
|
|
||||||
|
|
||||||
auto void add_part (const char *part, int len);
|
|
||||||
auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *);
|
|
||||||
|
|
||||||
/* Extend the symlink. */
|
|
||||||
void add_part (const char *part, int len)
|
|
||||||
{
|
|
||||||
int size = grub_strlen (symlink);
|
|
||||||
|
|
||||||
symlink = grub_realloc (symlink, size + len + 1);
|
|
||||||
if (! symlink)
|
|
||||||
return;
|
|
||||||
|
|
||||||
grub_strncat (symlink, part, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read in a symlink. */
|
|
||||||
grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
|
|
||||||
{
|
|
||||||
if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
|
|
||||||
{
|
|
||||||
unsigned int pos = 1;
|
|
||||||
|
|
||||||
/* The symlink is not stored as a POSIX symlink, translate it. */
|
|
||||||
while (pos < grub_le_to_cpu32 (entry->len))
|
|
||||||
{
|
|
||||||
if (addslash)
|
|
||||||
{
|
|
||||||
add_part ("/", 1);
|
|
||||||
addslash = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The current position is the `Component Flag'. */
|
|
||||||
switch (entry->data[pos] & 30)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
/* The data on pos + 2 is the actual data, pos + 1
|
|
||||||
is the length. Both are part of the `Component
|
|
||||||
Record'. */
|
|
||||||
add_part ((char *) &entry->data[pos + 2],
|
|
||||||
entry->data[pos + 1]);
|
|
||||||
if ((entry->data[pos] & 1))
|
|
||||||
addslash = 1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
add_part ("./", 2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
add_part ("../", 3);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
add_part ("/", 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* In pos + 1 the length of the `Component Record' is
|
|
||||||
stored. */
|
|
||||||
pos += entry->data[pos + 1] + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if `grub_realloc' failed. */
|
|
||||||
if (grub_errno)
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sua_off = (sizeof (node->dirents[0]) + node->dirents[0].namelen + 1
|
|
||||||
- (node->dirents[0].namelen % 2)
|
|
||||||
+ node->data->susp_skip);
|
|
||||||
sua_size = node->dirents[0].len - sua_off;
|
|
||||||
|
|
||||||
symlink = grub_malloc (1);
|
|
||||||
if (!symlink)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
*symlink = '\0';
|
|
||||||
|
|
||||||
if (grub_iso9660_susp_iterate (node, node->dir_off + sua_off,
|
|
||||||
sua_size, susp_iterate_sl))
|
|
||||||
{
|
|
||||||
grub_free (symlink);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return symlink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_off_t
|
static grub_off_t
|
||||||
|
@ -602,6 +510,23 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
int filename_alloc = 0;
|
int filename_alloc = 0;
|
||||||
enum grub_fshelp_filetype type;
|
enum grub_fshelp_filetype type;
|
||||||
grub_off_t len;
|
grub_off_t len;
|
||||||
|
char *symlink = 0;
|
||||||
|
int addslash = 0;
|
||||||
|
|
||||||
|
auto void add_part (const char *part, int len);
|
||||||
|
|
||||||
|
/* Extend the symlink. */
|
||||||
|
void add_part (const char *part, int len2)
|
||||||
|
{
|
||||||
|
int size = symlink ? grub_strlen (symlink) : 0;
|
||||||
|
|
||||||
|
symlink = grub_realloc (symlink, size + len2 + 1);
|
||||||
|
if (! symlink)
|
||||||
|
return;
|
||||||
|
|
||||||
|
symlink[size] = 0;
|
||||||
|
grub_strncat (symlink, part, len2);
|
||||||
|
}
|
||||||
|
|
||||||
auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
|
auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
|
||||||
|
|
||||||
|
@ -659,6 +584,56 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
type = GRUB_FSHELP_UNKNOWN;
|
type = GRUB_FSHELP_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
|
||||||
|
{
|
||||||
|
unsigned int pos = 1;
|
||||||
|
|
||||||
|
/* The symlink is not stored as a POSIX symlink, translate it. */
|
||||||
|
while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len))
|
||||||
|
{
|
||||||
|
if (addslash)
|
||||||
|
{
|
||||||
|
add_part ("/", 1);
|
||||||
|
addslash = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The current position is the `Component Flag'. */
|
||||||
|
switch (entry->data[pos] & 30)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
/* The data on pos + 2 is the actual data, pos + 1
|
||||||
|
is the length. Both are part of the `Component
|
||||||
|
Record'. */
|
||||||
|
add_part ((char *) &entry->data[pos + 2],
|
||||||
|
entry->data[pos + 1]);
|
||||||
|
if ((entry->data[pos] & 1))
|
||||||
|
addslash = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
add_part ("./", 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
add_part ("../", 3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
add_part ("/", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* In pos + 1 the length of the `Component Record' is
|
||||||
|
stored. */
|
||||||
|
pos += entry->data[pos + 1] + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if `grub_realloc' failed. */
|
||||||
|
if (grub_errno)
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -667,6 +642,9 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
for (; offset < len; offset += dirent.len)
|
for (; offset < len; offset += dirent.len)
|
||||||
{
|
{
|
||||||
|
symlink = 0;
|
||||||
|
addslash = 0;
|
||||||
|
|
||||||
if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
|
if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -709,7 +687,7 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
|
||||||
|
|
||||||
/* Setup a new node. */
|
/* Setup a new node. */
|
||||||
node->data = dir->data;
|
node->data = dir->data;
|
||||||
node->dir_off = offset;
|
node->symlink = symlink;
|
||||||
|
|
||||||
/* If the filetype was not stored using rockridge, use
|
/* If the filetype was not stored using rockridge, use
|
||||||
whatever is stored in the iso9660 filesystem. */
|
whatever is stored in the iso9660 filesystem. */
|
||||||
|
@ -838,7 +816,7 @@ grub_iso9660_dir (grub_device_t device, const char *path,
|
||||||
rootnode.data = data;
|
rootnode.data = data;
|
||||||
rootnode.alloc_dirents = 0;
|
rootnode.alloc_dirents = 0;
|
||||||
rootnode.have_dirents = 1;
|
rootnode.have_dirents = 1;
|
||||||
rootnode.dir_off = 0;
|
rootnode.symlink = 0;
|
||||||
rootnode.dirents[0] = data->voldesc.rootdir;
|
rootnode.dirents[0] = data->voldesc.rootdir;
|
||||||
|
|
||||||
/* Use the fshelp function to traverse the path. */
|
/* Use the fshelp function to traverse the path. */
|
||||||
|
@ -881,7 +859,7 @@ grub_iso9660_open (struct grub_file *file, const char *name)
|
||||||
rootnode.data = data;
|
rootnode.data = data;
|
||||||
rootnode.alloc_dirents = 0;
|
rootnode.alloc_dirents = 0;
|
||||||
rootnode.have_dirents = 1;
|
rootnode.have_dirents = 1;
|
||||||
rootnode.dir_off = 0;
|
rootnode.symlink = 0;
|
||||||
rootnode.dirents[0] = data->voldesc.rootdir;
|
rootnode.dirents[0] = data->voldesc.rootdir;
|
||||||
|
|
||||||
/* Use the fshelp function to traverse the path. */
|
/* Use the fshelp function to traverse the path. */
|
||||||
|
|
Loading…
Reference in a new issue