From cdb980b37f40dc2c41891434c7736e49da53756e Mon Sep 17 00:00:00 2001 From: Robert Yang Date: Wed, 31 Dec 2014 16:47:52 +0800 Subject: [PATCH 5/9] linux/syslinux: implement handle_adv_on_ext() It reads adv if found on the device, or resets syslinux_adv, or update the adv if update adv only. Upstream-Status: Submitted Signed-off-by: Robert Yang Tested-by: Du Dolpher --- linux/syslinux.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/linux/syslinux.c b/linux/syslinux.c index 247c86a..de5d272 100755 --- a/linux/syslinux.c +++ b/linux/syslinux.c @@ -421,6 +421,103 @@ int install_bootblock(int fd, const char *device) static int handle_adv_on_ext(void) { + int i, retval, found_file; + int need_close = 2; /* 2 means no need extra close */ + char *filenames[2] = {"ldlinux.sys", "extlinux.sys"}; + char *filename; + ext2_ino_t newino; + ext2_file_t e2_file; + struct ext2_inode inode; + + for (i = 0; i < 2; i++) { + filename = filenames[i]; + found_file = 0; + retval = ext2fs_namei(e2fs, root, cwd, filename, &newino); + if (retval == 0) { + found_file = 1; + } else + continue; + + need_close = i; + + retval = ext2fs_file_open(e2fs, newino, EXT2_FLAG_RW, &e2_file); + if (retval) { + fprintf(stderr, "%s: failed to open %s\n", + program, filename); + goto fail; + } + + retval = ext2fs_read_inode(e2fs, newino, &inode); + if (retval) { + fprintf(stderr, "%s: error while reading inode: %u, file: %s\n", + program, newino, filename); + goto fail; + } + + /* Check the size to see if too small to read */ + if (inode.i_size < 2 * ADV_SIZE) { + if (opt.update_only == -1) { + fprintf(stderr, "%s: failed to write auxilliary data\n\ + the size of %s is too small (need --update)?\n", + program, filename); + retval = -1; + goto fail; + } + syslinux_reset_adv(syslinux_adv); + found_file = 0; + break; + } + + /* Read the adv */ + retval = ext_file_read(e2_file, syslinux_adv, 2 * ADV_SIZE, + inode.i_size - 2 * ADV_SIZE, "ADV"); + if (retval == -1) + goto fail; + if (retval == 2 * ADV_SIZE) { + retval = syslinux_validate_adv(syslinux_adv); + /* Read the adv successfully */ + if (retval == 0) + break; + } + + /* Close the file if reaches here, otherwise we leave the file + * open in case we need write it */ + need_close = 2; + retval = ext2fs_file_close(e2_file); + if (retval) { + fprintf(stderr, "%s: error while closing %s\n", + program, filename); + return retval; + } + } + + if (!found_file) { + if (opt.update_only == -1) { + fprintf(stderr, "%s: no ldlinux.sys or extlinux.sys found on the device\n", + program); + return -1; + } + syslinux_reset_adv(syslinux_adv); + } + + /* The modify_adv will reset the adv if opt.reset_adv */ + if (modify_adv() < 0) { + fprintf(stderr, "%s: error while modifying adv\n", program); + retval = -1; + goto fail; + } + + /* Write adv if update_only == -1 and found file */ + if (opt.update_only == -1 && found_file) { + if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE , + inode.i_size - 2 * ADV_SIZE) == -1) + goto fail; + } + +fail: + if (need_close != 2) + (void) ext2fs_file_close(e2_file); + return retval; } /* Write files, adv, boot sector */ -- 1.9.1