X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Flib%2Fefi.c;h=a4ce5cfe21cdd6fe8ea942cd133f05dba025bddb;hb=438378f384ede73602fcdfd288e45ac41d933bb0;hp=dcc5e9195c6f91729e6ebb24fd9fd12cf938342e;hpb=c66ed5866f7969a0340b36dc361c7e20043dcc5c;p=debian%2Fefibootmgr diff --git a/src/lib/efi.c b/src/lib/efi.c index dcc5e91..a4ce5cf 100644 --- a/src/lib/efi.c +++ b/src/lib/efi.c @@ -18,8 +18,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define _FILE_OFFSET_BITS 64 - +#include #include #include #include @@ -34,9 +33,10 @@ #include #include #include +#include #include #include -typedef __u64 u64; +#include #include #include "efi.h" #include "efichar.h" @@ -172,9 +172,12 @@ create_or_edit_variable(efi_variable_t *var) static int select_boot_var_names(const struct dirent *d) { - int num, rc; - rc = sscanf(d->d_name, "Boot0%03x-%*s", &num); - return rc; + if (!strncmp(d->d_name, "Boot", 4) && + isxdigit(d->d_name[4]) && isxdigit(d->d_name[5]) && + isxdigit(d->d_name[6]) && isxdigit(d->d_name[7]) && + d->d_name[8] == '-') + return 1; + return 0; } int @@ -543,7 +546,8 @@ char *make_disk_load_option(char *p, char *disk) * make_net_load_option() * @data - load option returned * - * Returns 0 on error, length of load option created on success. + * Returns NULL on error, or p advanced by length of load option + * created on success. */ char *make_net_load_option(char *p, char *iface) { @@ -561,29 +565,37 @@ char *make_net_load_option(char *p, char *iface) fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { perror("Cannot get control socket"); + goto out; } err = ioctl(fd, SIOCETHTOOL, &ifr); if (err < 0) { perror("Cannot get driver information"); + goto out; } - - err = sscanf(drvinfo.bus_info, "%2x:%2x.%x", &bus, &slot, &func); - if (err == 0) { - perror("Couldn't parse device location string."); + /* The domain part was added in 2.6 kernels. Test for that first. */ + err = sscanf(drvinfo.bus_info, "%*x:%2x:%2x.%x", &bus, &slot, &func); + if (err != 3) { + err = sscanf(drvinfo.bus_info, "%2x:%2x.%x", &bus, &slot, &func); + if (err != 3) { + perror("Couldn't parse device location string."); + goto out; + } } - p += make_acpi_device_path(p, opts.acpi_hid, opts.acpi_uid); - p += make_pci_device_path(p, bus, (uint8_t)slot, (uint8_t)func); - err = ioctl(fd, SIOCGIFHWADDR, &ifr); if (err < 0) { perror("Cannot get hardware address."); + goto out; } + p += make_acpi_device_path(p, opts.acpi_hid, opts.acpi_uid); + p += make_pci_device_path(p, bus, (uint8_t)slot, (uint8_t)func); p += make_mac_addr_device_path(p, ifr.ifr_ifru.ifru_hwaddr.sa_data, 0); p += make_end_device_path (p); return(p); + out: + return NULL; } /** @@ -618,10 +630,11 @@ make_linux_load_option(void *data) if (opts.iface) { p = (char *)make_net_load_option(p, opts.iface); } - else { p = (char *)make_disk_load_option(p, opts.iface); } + if (p == NULL) + return 0; load_option->file_path_list_length = p - q; @@ -693,14 +706,57 @@ append_extra_args_unicode(void *data, unsigned long maxchars) return 0; } +static unsigned long +append_extra_args_file(void *data, unsigned long maxchars) +{ + char *p = data; + char *file = opts.extra_opts_file; + int fd = STDIN_FILENO; + ssize_t num_read=0; + unsigned long appended=0; + + if (!data) return 0; + + if (file && strncmp(file, "-", 1)) + fd = open(file, O_RDONLY); + + if (fd == -1) { + perror("Failed to open extra arguments file"); + exit(1); + } + + do { + num_read = read(fd, p, maxchars - appended); + if (num_read < 0) { + perror("Error reading extra arguments file"); + break; + } + else if (num_read>0) { + appended += num_read; + p += num_read; + } + } while (num_read > 0 && ((maxchars - appended) > 0)); + + if (fd != STDIN_FILENO) + close(fd); + + return appended; +} + static unsigned long append_extra_args(void *data, unsigned long maxchars) { - if (opts.unicode) - return append_extra_args_unicode(data, maxchars); + unsigned long bytes_written=0; + + if (opts.extra_opts_file) + bytes_written += append_extra_args_file(data, maxchars); + + if (opts.unicode) + bytes_written += append_extra_args_unicode(data, maxchars - bytes_written); else - return append_extra_args_ascii(data, maxchars); + bytes_written += append_extra_args_ascii(data, maxchars - bytes_written); + return bytes_written; } @@ -717,7 +773,7 @@ make_linux_efi_variable(efi_variable_t *var, memset(buffer, 0, sizeof(buffer)); /* VariableName needs to be BootXXXX */ - sprintf(buffer, "Boot%04x", free_number); + sprintf(buffer, "Boot%04X", free_number); efichar_from_char(var->VariableName, buffer, 1024);