aboutsummaryrefslogtreecommitdiffstats
path: root/extlinux/main.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-06-24 13:30:49 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-06-24 13:30:49 -0700
commit8ab23dd287bba04d19db1e66828320d12739c0e3 (patch)
treec7b494f18dbfb3cf80ef356cbfaa3880371998cb /extlinux/main.c
parent2e8b89f8b2d711a1689067834113483610fa18cd (diff)
parent06b5bd5a470cf4aad212aa81a26c8a5e03a48b2c (diff)
downloadsyslinux-8ab23dd287bba04d19db1e66828320d12739c0e3.tar.gz
syslinux-8ab23dd287bba04d19db1e66828320d12739c0e3.tar.xz
syslinux-8ab23dd287bba04d19db1e66828320d12739c0e3.zip
Merge branch 'master' of ssh://terminus.zytor.com/pub/git/syslinux/syslinuxsyslinux-4.00-pre59
Diffstat (limited to 'extlinux/main.c')
-rw-r--r--extlinux/main.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/extlinux/main.c b/extlinux/main.c
index 7b0b467b..ad173516 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -340,13 +340,15 @@ int install_bootblock(int fd, const char *device)
int ext2_fat_install_file(const char *path, int devfd, struct stat *rst)
{
- char *file;
+ char *file, *oldfile;
int fd = -1, dirfd = -1;
int modbytes;
asprintf(&file, "%s%sldlinux.sys",
path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
- if (!file) {
+ asprintf(&oldfile, "%s%sextlinux.sys",
+ path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+ if (!file || !oldfile) {
perror(program);
return 1;
}
@@ -404,6 +406,17 @@ int ext2_fat_install_file(const char *path, int devfd, struct stat *rst)
close(dirfd);
close(fd);
+
+ /* Look if we have the old filename */
+ fd = open(oldfile, O_RDONLY);
+ if (fd >= 0) {
+ clear_attributes(fd);
+ close(fd);
+ unlink(oldfile);
+ }
+
+ free(file);
+ free(oldfile);
return 0;
bail:
@@ -412,6 +425,8 @@ bail:
if (fd >= 0)
close(fd);
+ free(file);
+ free(oldfile);
return 1;
}
@@ -662,17 +677,31 @@ static int open_device(const char *path, struct stat *st, const char **_devname)
return devfd;
}
-static int ext_read_adv(const char *path, const char *cfg, int devfd)
+static int btrfs_read_adv(int devfd)
{
- if (fs_type == BTRFS) { /* btrfs "ldlinux.sys" is in 64k blank area */
- if (xpread(devfd, syslinux_adv, 2 * ADV_SIZE,
- BTRFS_ADV_OFFSET) != 2 * ADV_SIZE) {
- perror("btrfs writing adv");
- return 1;
- }
- return 0;
+ if (xpread(devfd, syslinux_adv, 2 * ADV_SIZE, BTRFS_ADV_OFFSET)
+ != 2 * ADV_SIZE)
+ return -1;
+
+ return syslinux_validate_adv(syslinux_adv) ? 1 : 0;
+}
+
+static int ext_read_adv(const char *path, int devfd, const char **namep)
+{
+ int err;
+ const char *name;
+
+ if (fs_type == BTRFS) {
+ /* btrfs "ldlinux.sys" is in 64k blank area */
+ return btrfs_read_adv(devfd);
+ } else {
+ err = read_adv(path, name = "ldlinux.sys");
+ if (err == 2) /* ldlinux.sys does not exist */
+ err = read_adv(path, name = "extlinux.sys");
+ if (namep)
+ *namep = name;
+ return err;
}
- return read_adv(path, cfg);
}
static int ext_write_adv(const char *path, const char *cfg, int devfd)
@@ -706,12 +735,13 @@ int install_loader(const char *path, int update_only)
}
/* Read a pre-existing ADV, if already installed */
- if (opt.reset_adv)
+ if (opt.reset_adv) {
syslinux_reset_adv(syslinux_adv);
- else if (ext_read_adv(path, "ldlinux.sys", devfd) < 0) {
+ } else if (ext_read_adv(path, devfd, NULL) < 0) {
close(devfd);
return 1;
}
+
if (modify_adv() < 0) {
close(devfd);
return 1;
@@ -742,6 +772,7 @@ int install_loader(const char *path, int update_only)
*/
int modify_existing_adv(const char *path)
{
+ const char *filename;
int devfd;
devfd = open_device(path, NULL, NULL);
@@ -750,7 +781,7 @@ int modify_existing_adv(const char *path)
if (opt.reset_adv)
syslinux_reset_adv(syslinux_adv);
- else if (ext_read_adv(path, "ldlinux.sys", devfd) < 0) {
+ else if (ext_read_adv(path, devfd, &filename) < 0) {
close(devfd);
return 1;
}
@@ -758,7 +789,7 @@ int modify_existing_adv(const char *path)
close(devfd);
return 1;
}
- if (ext_write_adv(path, "ldlinux.sys", devfd) < 0) {
+ if (ext_write_adv(path, filename, devfd) < 0) {
close(devfd);
return 1;
}