Imported Debian patch 0.5.4-1 debian/0.5.4-1
authorBdale Garbee <bdale@gag.com>
Mon, 25 Feb 2008 00:30:01 +0000 (17:30 -0700)
committerBdale Garbee <bdale@gag.com>
Tue, 20 May 2008 05:06:24 +0000 (23:06 -0600)
Makefile
debian/changelog
doc/ChangeLog
efibootmgr.spec
src/efibootmgr/efibootmgr.c
src/efibootmgr/efibootmgr.c.orig [deleted file]
src/efibootmgr/module.mk
src/lib/efi.c
src/lib/efi.c.orig [deleted file]
src/lib/gpt.c
src/lib/unparse_path.c

index 77e640dd0179c8e662450b27daa49c43a724c151..c4fbee09271a32fd4bae42277b3e5d72c6359bfc 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,14 @@
   default: all
 
-  RELEASE_DATE := "09-Nov-2005"
+  RELEASE_DATE := "03-Jan-2008"
   RELEASE_MAJOR := 0
   RELEASE_MINOR := 5
-  RELEASE_SUBLEVEL := 3
+  RELEASE_SUBLEVEL := 4
   RELEASE_EXTRALEVEL :=
   RELEASE_NAME := efibootmgr
   RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_SUBLEVEL)$(RELEASE_EXTRALEVEL)
 
-  CFLAGS += -DEFIBOOTMGR_VERSION=\"$(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_SUBLEVEL)$(RELEASE_EXTRALEVEL)\" \
+  CFLAGS = $(EXTRA_CFLAGS) -DEFIBOOTMGR_VERSION=\"$(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_SUBLEVEL)$(RELEASE_EXTRALEVEL)\" \
            -Wall -g -D_FILE_OFFSET_BITS=64
 
   LDFLAGS += -lz
@@ -58,7 +58,7 @@
        cp -a ../$(RELEASE_NAME) ../$(RELEASE_STRING)
        find ../$(RELEASE_STRING) -name CVS -type d -depth -exec rm -rf \{\} \;
        sync; sync; sync;
-       cd ..; tar cvzf $(RELEASE_STRING).tar.gz $(RELEASE_STRING)
+       cd ..; tar cvzf $(RELEASE_STRING).tar.gz --exclude=.git --exclude=\*~ $(RELEASE_STRING)
        mv ../$(RELEASE_STRING).tar.gz .
        rm -rf ../$(RELEASE_STRING)
 
index 5bb9b543eaf85985073d9a001e6e4d48d1784b21..5d87232788b6bbf47daf5c86b950699e0a0b6816 100644 (file)
@@ -1,3 +1,9 @@
+efibootmgr (0.5.4-1) unstable; urgency=low
+
+  * new upstream version
+
+ -- Bdale Garbee <bdale@gag.com>  Sun, 24 Feb 2008 17:30:01 -0700
+
 efibootmgr (0.5.3-3) unstable; urgency=low
 
   * fix FTBFS, closes: #450448
index eada84fd2df4fa0b296eba95cab451481243f671..adfc17d56d4721920f6332c3e412c12f653cdee1 100644 (file)
@@ -1,6 +1,99 @@
-* Wed Nov 9 2005 Matt Domsch <Matt_Domsch@dell.com>
-- released v0.5.2.2 as v0.5.3, no changes
-       
+commit 6e6bf6fc7665851798a6c2c92893ebb629e42aff
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Fri Jan 11 15:08:12 2008 -0600
+
+    replacing elilo < 3.6-6, not -5
+    
+    per conversation with clumens.
+
+commit 4c1fd35da4d0478074e08c10225eb590576acf91
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Thu Jan 3 12:19:28 2008 -0600
+
+    RPM spec rewrite for Fedora inclusion
+    
+    efibootmgr is being split out of the elilo SRPM in Fedora, into its
+    own SRPM.
+
+commit 833cf4c1266ef72357948299008a22bfb80aa3f3
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Thu Jan 3 12:18:31 2008 -0600
+
+    Makefile cleanups
+    
+    bump version
+    
+    take an EXTRA_CFLAGS argument so rpmbuild can give us it's CFLAGS
+    without overriding ours.
+    
+    exclude .git and *~ files from the tarball.
+
+commit f0a8b91ba45ff4cf251805cc29aed4f8672c1801
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Thu Jan 3 12:16:35 2008 -0600
+
+    src/lib/efi.c: include linux/types.h
+    
+    patch from Fedora.
+
+commit f387d5c5bde5d7129e41638e92faa2d38b7ad5a1
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Thu Jan 3 12:15:18 2008 -0600
+
+    make sure GPT_HEADER_SIGNATURE is a 64-bit value
+    
+    patch from Debian / Ubuntu 0.5.3-3ubuntu1.
+
+commit 7b53efa45112f28e97451bdc16e6c6a68740bd79
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Mon Nov 12 13:31:32 2007 -0600
+
+    avoid more unaligned access warnings
+
+commit 048197821f9ae2ef9e0c2bd4065649e72332e2dc
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Mon Nov 12 12:25:42 2007 -0600
+
+    cleanup a few unaligned access warnings
+
+commit fa3942b34f1533659af8fe3f6fffb3b4acf4ee10
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Mon Nov 12 12:12:37 2007 -0600
+
+    cleanup exit values a little
+
+commit c7e236783a79b6977df0ba03db0f92fabffc4b31
+Author: Doug Chapman <doug.chapman@hp.com>
+Date:   Mon Nov 12 11:32:12 2007 -0500
+
+    patch to make efibootmgr have non-zero exit code on errors
+    
+    We have some automated tools that use efibootmgr which are having a hard
+    time detecting when efibootmgr fails since it exits with 0 on many
+    failures.  This patch catches (most) errors and exits with non-zero.  I
+    also added several error messages for to make it more obvious what was
+    wrong with the command line arguments.
+    
+    Signed-off-by: Matt Domsch <Matt_Domsch@dell.com>
+
+commit ecd3c24cb6bee5072ff6d1292456ee3b2cc91019
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Mon Jul 9 16:47:50 2007 +0000
+
+    add -lz to libs, needed when libpci happens to need it
+
+commit e192a055e0803263b71f89db732de73d5cf4de9b
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Mon Jul 9 16:23:34 2007 +0000
+
+    apply patch from Dave Jiang <djiang@mvista.com> to enable cross-building
+
+commit 0ee8ecc10109b91d0a77098d5596f56780c862d8
+Author: Matt Domsch <Matt_Domsch@dell.com>
+Date:   Thu Aug 11 17:37:04 2005 +0000
+
+    v0.5.2.2
+
 * Thu Aug 11 2005 Matt Domsch <Matt_Domsch@dell.com>
 - applied patch from Rogerio Timmers which adds a new option -@ <file>,
   which takes extra variable parameters from <file>, or - from stdin.
index 5a8b832ee80108b9428bc1b0cfec6b70d3c3e999..6990bcd5180e918a41ac9139e616afd112397097 100644 (file)
@@ -1,38 +1,52 @@
 Summary: EFI Boot Manager
 Name: efibootmgr
-Version: 0.5.0
-Release: 0
+Version: 0.5.4
+Release: 1%{?dist}
 Group: System Environment/Base
-Copyright: GPL
-Vendor: Dell linux.dell.com
-Packager: Matt Domsch <Matt_Domsch@dell.com>
+License: GPLv2+
+URL: http://linux.dell.com/%{name}/
+BuildRequires: pciutils-devel, zlib-devel
+BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXXXX)
+# EFI/UEFI don't exist on PPC
+ExclusiveArch: i386 x86_64 ia64
 
+# for RHEL / Fedora when efibootmgr was part of the elilo package
+Conflicts: elilo < 3.6-6
+Obsoletes: elilo < 3.6-6
 
-Source0: http://linux.dell.com/efibootmgr/permalink/efibootmgr-%{version}.tar.gz
-Source1: http://linux.dell.com/efibootmgr/permalink/efibootmgr-%{version}.tar.gz.sign
+Source0: http://linux.dell.com/%{name}/permalink/%{name}-%{version}.tar.gz
 
 %description
-efibootmgr displays and allows the user to edit the Intel Extensible
+%{name} displays and allows the user to edit the Intel Extensible
 Firmware Interface (EFI) Boot Manager variables.  Additional
 information about EFI can be found at
-http://developer.intel.com/technology/efi/efi.htm
+http://developer.intel.com/technology/efi/efi.htm and http://uefi.org/.
 
 %prep
-%setup
+%setup -q
 %build
-make
+make %{?_smp_mflags} EXTRA_CFLAGS='%{optflags}'
 %install
-install --group=root --owner=root --mode 555 src/efibootmgr/efibootmgr $RPM_BUILD_ROOT/usr/sbin
-install --group=root --owner=root --mode 444 src/man/man8/efibootmgr.8 $RPM_BUILD_ROOT/usr/share/man/man8
+rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_sbindir} %{buildroot}%{_mandir}/man8
+install -p --mode 755 src/%{name}/%{name} %{buildroot}%{_sbindir}
+gzip -9 -c src/man/man8/%{name}.8 > src/man/man8/%{name}.8.gz
+touch -r src/man/man8/%{name}.8 src/man/man8/%{name}.8.gz
+install -p --mode 644 src/man/man8/%{name}.8.gz %{buildroot}%{_mandir}/man8
 
-%files
-/usr/sbin/efibootmgr
-/usr/share/man/man8/efibootmgr.8
-%doc README
-%doc INSTALL
+%clean
+rm -rf %{buildroot}
 
+%files
+%defattr(-,root,root,-)
+%{_sbindir}/%{name}
+%{_mandir}/man8/%{name}.8.gz
+%doc README INSTALL COPYING
     
 %changelog
+* Thu Jan  3 2008 Matt Domsch <Matt_Domsch@dell.com> 0.5.4-1
+- split efibootmgr into its own RPM for Fedora/RHEL.
+
 * Thu Aug 24 2004 Matt Domsch <Matt_Domsch@dell.com>
 - new home linux.dell.com
 
index 7aeb1868e0e9bc7e1e780b92a6b3ab0fbd68a895..5db0d9e65e1304d17dbeef09e6fe6631614f69f7 100644 (file)
@@ -436,7 +436,10 @@ delete_boot_var(uint16_t num)
                status = delete_variable(&var);
        }
 
-       if (status) return status;
+       if (status) {
+               fprintf (stderr,"\nboot entry: %X not found\n\n",num);
+               return status;
+       }
        list_for_each_safe(pos, n, &boot_entry_list) {
                boot = list_entry(pos, var_entry_t, list);
                if (boot->num == num) {
@@ -583,6 +586,21 @@ unparse_boot_order(uint16_t *order, int length)
        printf("\n");
 }
 
+static int
+is_current_boot_entry(int b)
+{
+       list_t *pos;
+       var_entry_t *boot;
+
+       list_for_each(pos, &boot_entry_list) {
+               boot = list_entry(pos, var_entry_t, list);
+               if (boot->num == b)
+                       return 1;
+       }
+       return 0;
+}
+
+
 static int
 parse_boot_order(char *buffer, uint16_t *order, int length)
 {
@@ -592,6 +610,16 @@ parse_boot_order(char *buffer, uint16_t *order, int length)
        for (i=0; i<length && *buffer; i++) {
                rc = sscanf(buffer, "%x", &num);
                if (rc == 1) order[i] = num & 0xFFFF;
+               else {
+                       fprintf(stderr,"\nInvalid hex characters in boot order: %s\n\n",buffer);
+                       return -1;
+               }
+               /* make sure this is an existing boot entry */
+               if (!is_current_boot_entry(order[i])) {
+                       fprintf (stderr,"\nboot entry %X does not exist\n\n",order[i]);
+                       return -1;
+               }
+
                /* Advance to the comma */ 
                while (*buffer && *buffer != ',') buffer++;
                /* Advance through the comma(s) */
@@ -612,7 +640,10 @@ set_boot_order()
        fill_var(&boot_order, "BootOrder");
 
        boot_order.DataSize = parse_boot_order(opts.bootorder, n, 1024/sizeof(uint16_t)) * sizeof(uint16_t);
-       return create_or_edit_variable(&boot_order);
+       if (boot_order.DataSize < 0)
+               return 1;
+       else
+               return create_or_edit_variable(&boot_order);
 }
 
 static void
@@ -724,7 +755,9 @@ set_active_state()
                        }
                }
        }
-       return EFI_SUCCESS;
+       /* if we reach here then the bootnumber supplied was not found */
+       fprintf(stderr,"\nboot entry %x not found\n\n",opts.bootnum);
+       return EFI_NOT_FOUND;
 }
 
 
@@ -849,6 +882,10 @@ parse_opts(int argc, char **argv)
                case 'b':
                        rc = sscanf(optarg, "%X", &num);
                        if (rc == 1) opts.bootnum = num;
+                       else {
+                               fprintf (stderr,"invalid hex value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'c':
                        opts.create = 1;
@@ -859,10 +896,18 @@ parse_opts(int argc, char **argv)
                case 'e':
                        rc = sscanf(optarg, "%d", &num);
                        if (rc == 1) opts.edd_version = num;
+                       else {
+                               fprintf (stderr,"invalid numeric value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'E':
                        rc = sscanf(optarg, "%x", &num);
                        if (rc == 1) opts.edd10_devicenum = num;
+                       else {
+                               fprintf (stderr,"invalid hex value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'g':
                        opts.forcegpt = 1;
@@ -870,6 +915,10 @@ parse_opts(int argc, char **argv)
                case 'H':
                        rc = sscanf(optarg, "%x", &num);
                        if (rc == 1) opts.acpi_hid = num;
+                       else {
+                               fprintf (stderr,"invalid hex value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'i':
                        opts.iface = optarg;
@@ -886,6 +935,10 @@ parse_opts(int argc, char **argv)
                case 'n':
                        rc = sscanf(optarg, "%x", &num);
                        if (rc == 1) opts.bootnext = num;
+                       else {
+                               fprintf (stderr,"invalid hex value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'o':
                        opts.bootorder = optarg;
@@ -896,6 +949,10 @@ parse_opts(int argc, char **argv)
                case 'p':
                        rc = sscanf(optarg, "%u", &num);
                        if (rc == 1) opts.part = num;
+                       else {
+                               fprintf (stderr,"invalid numeric value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'q':
                        opts.quiet = 1;
@@ -909,6 +966,10 @@ parse_opts(int argc, char **argv)
                                opts.timeout = num;
                                opts.set_timeout = 1;
                        }
+                       else {
+                               fprintf (stderr,"invalid numeric value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'T':
                        opts.delete_timeout = 1;
@@ -920,6 +981,10 @@ parse_opts(int argc, char **argv)
                case 'U':
                        rc = sscanf(optarg, "%x", &num);
                        if (rc == 1) opts.acpi_uid = num;
+                       else {
+                               fprintf (stderr,"invalid hex value %s\n",optarg);
+                               exit(1);
+                       }
                        break;
                case 'v':
                        opts.verbose = 1;
@@ -928,6 +993,10 @@ parse_opts(int argc, char **argv)
                                if (!strcmp(optarg, "vv")) opts.verbose = 3;
                                rc = sscanf(optarg, "%d", &num);
                                if (rc == 1)  opts.verbose = num;
+                               else {
+                                       fprintf (stderr,"invalid numeric value %s\n",optarg);
+                                       exit(1);
+                               }
                        }
                        break;
                case 'V':
@@ -958,6 +1027,7 @@ main(int argc, char **argv)
        struct dirent  **boot_names = NULL;
        var_entry_t *new_boot = NULL;
        int num, num_boot_names=0;
+       efi_status_t ret=0;
 
        set_default_opts();
        parse_opts(argc, argv);
@@ -980,53 +1050,68 @@ main(int argc, char **argv)
                set_var_nums("Boot%04X-%*s", &boot_entry_list);
 
                if (opts.delete_boot) {
-                       if (opts.bootnum == -1)
+                       if (opts.bootnum == -1) {
                                fprintf(stderr, "\nYou must specify a boot entry to delete (see the -b option).\n\n");
+                               return 1;
+                       }
                        else
-                               delete_boot_var(opts.bootnum);
+                               ret = delete_boot_var(opts.bootnum);
                }
 
                if (opts.active >= 0) {
-                       set_active_state();
+                       if (opts.bootnum == -1) {
+                               fprintf(stderr, "\nYou must specify a boot entry to delete (see the -b option).\n\n");
+                               return 1;
+                       }
+                       else
+                               ret=set_active_state();
                }
        }
 
        if (opts.create) {
                warn_duplicate_name(&boot_entry_list);
                new_boot = make_boot_var(&boot_entry_list);
+               if (!new_boot)
+                       return 1;
+
                /* Put this boot var in the right BootOrder */
                if (!opts.testfile && new_boot)
-                       add_to_boot_order(new_boot->num);
+                       ret=add_to_boot_order(new_boot->num);
        }
 
        if (!opts.testfile) {
 
                if (opts.delete_bootorder) {
-                       delete_var("BootOrder");
+                       ret=delete_var("BootOrder");
                }
 
                if (opts.bootorder) {
-                       set_boot_order();
+                       ret=set_boot_order();
                }
 
 
                if (opts.delete_bootnext) {
-                       delete_var("BootNext");
+                       ret=delete_var("BootNext");
                }
 
                if (opts.delete_timeout) {
-                       delete_var("Timeout");
+                       ret=delete_var("Timeout");
                }
 
                if (opts.bootnext >= 0) {
-                       set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
+                       if (!is_current_boot_entry(opts.bootnext & 0xFFFF)){
+                               fprintf (stderr,"\n\nboot entry %X does not exist\n\n",
+                                       opts.bootnext);
+                               return 1;
+                       }
+                       ret=set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
                }
 
                if (opts.set_timeout) {
-                       set_boot_u16("Timeout", opts.timeout);
+                       ret=set_boot_u16("Timeout", opts.timeout);
                }
 
-               if (!opts.quiet) {
+               if (!opts.quiet && ret == 0) {
                        num = read_boot_u16("BootNext");
                        if (num != -1 ) {
                                printf("BootNext: %04X\n", num);
@@ -1045,6 +1130,8 @@ main(int argc, char **argv)
        }
        free_dirents(boot_names, num_boot_names);
        free_vars(&boot_entry_list);
+       if (ret)
+               return 1;
        return 0;
 }
 
diff --git a/src/efibootmgr/efibootmgr.c.orig b/src/efibootmgr/efibootmgr.c.orig
deleted file mode 100644 (file)
index 5a1a0d9..0000000
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
-  efibootmgr.c - Manipulates EFI variables as exported in /proc/efi/vars
-
-  Copyright (C) 2001-2004 Dell, Inc. <Matt_Domsch@dell.com>
-
-    This program 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 2 of the License, or
-    (at your option) any later version.
-
-    This program 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 this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-  This must tie the EFI_DEVICE_PATH to /boot/efi/elilo.efi
-  The  EFI_DEVICE_PATH will look something like:
-    ACPI device path, length 12 bytes
-    Hardware Device Path, PCI, length 6 bytes
-    Messaging Device Path, SCSI, length 8 bytes, or ATAPI, length ??
-    Media Device Path, Hard Drive, partition XX, length 30 bytes
-    Media Device Path, File Path, length ??
-    End of Hardware Device Path, length 4
-    Arguments passed to elilo, as UCS-2 characters, length ??
-
-*/
-
-#define _GNU_SOURCE
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <getopt.h>
-#include "list.h"
-#include "efi.h"
-#include "efichar.h"
-#include "unparse_path.h"
-#include "disk.h"
-#include "efibootmgr.h"
-
-
-#ifndef EFIBOOTMGR_VERSION
-#define EFIBOOTMGR_VERSION "unknown (fix Makefile!)"
-#endif
-
-
-typedef struct _var_entry {
-       struct dirent *name;
-       uint16_t       num;
-       efi_variable_t var_data;
-       list_t         list;
-} var_entry_t;
-
-
-/* global variables */
-static LIST_HEAD(boot_entry_list);
-static LIST_HEAD(blk_list);
-efibootmgr_opt_t opts;
-
-static inline void
-var_num_from_name(const char *pattern, char *name, uint16_t *num)
-{
-       sscanf(name, pattern, num);
-}
-
-static void
-fill_bootvar_name(char *dest, size_t len, const char *name)
-{
-       efi_guid_t guid = EFI_GLOBAL_VARIABLE;
-       char text_uuid[40];
-       efi_guid_unparse(&guid, text_uuid);
-       snprintf(dest, len, "%s-%s", name, text_uuid);
-}
-
-static void
-fill_var(efi_variable_t *var, const char *name)
-{
-       efi_guid_t guid = EFI_GLOBAL_VARIABLE;
-
-       efichar_from_char(var->VariableName, name, 1024);
-       memcpy(&var->VendorGuid, &guid, sizeof(guid));
-       var->Attributes = EFI_VARIABLE_NON_VOLATILE
-               | EFI_VARIABLE_BOOTSERVICE_ACCESS
-               | EFI_VARIABLE_RUNTIME_ACCESS;
-}
-
-static void
-free_vars(list_t *head)
-{
-       list_t *pos, *n;
-       var_entry_t *boot;
-
-       list_for_each_safe(pos, n, head) {
-               boot = list_entry(pos, var_entry_t, list);
-               list_del(&(boot->list));
-               free(boot);
-       }
-}
-
-static void
-read_vars(struct dirent **namelist,
-         int num_boot_names,
-         list_t *head)
-{
-       efi_status_t status;
-       var_entry_t *entry;
-       int i;
-
-       if (!namelist) return;
-
-       for (i=0; i < num_boot_names; i++)
-       {
-               if (namelist[i]) {
-                       entry = malloc(sizeof(var_entry_t));
-                       if (!entry) return;
-                       memset(entry, 0, sizeof(var_entry_t));
-
-                       status = read_variable(namelist[i]->d_name,
-                                              &entry->var_data);
-                       if (status != EFI_SUCCESS) break;
-                       entry->name = namelist[i];
-                       list_add_tail(&entry->list, head);
-               }
-       }
-       return;
-}
-
-
-
-
-
-static void
-free_dirents(struct dirent **ptr, int num_dirents)
-{
-       int i;
-       if (!ptr) return;
-       for (i=0; i < num_dirents; i++) {
-               if (ptr[i]) {
-                       free(ptr[i]);
-                       ptr[i] = NULL;
-               }
-       }
-       free(ptr);
-}
-
-
-
-static int
-compare(const void *a, const void *b)
-{
-       int rc = -1;
-       uint32_t n1, n2;
-       memcpy(&n1, a, sizeof(n1));
-       memcpy(&n2, b, sizeof(n2));
-       if (n1 < n2) rc = -1;
-       if (n1 == n2) rc = 0;
-       if (n2 > n2) rc = 1;
-       return rc;
-}
-
-
-/*
-  Return an available boot variable number,
-  or -1 on failure.
-*/
-static int
-find_free_boot_var(list_t *boot_list)
-{
-       int num_vars=0, i=0, found;
-       uint16_t *vars, free_number;
-       list_t *pos;
-       var_entry_t *boot;
-       list_for_each(pos, boot_list) {
-               num_vars++;
-       }
-       vars = malloc(sizeof(uint16_t) * num_vars);
-       if (!vars) return -1;
-       memset(vars, 0, sizeof(uint16_t) * num_vars);
-
-       list_for_each(pos, boot_list) {
-               boot = list_entry(pos, var_entry_t, list);
-               vars[i] = boot->num;
-                       i++;
-       }
-       qsort(vars, i, sizeof(uint16_t), compare);
-       found = 1;
-
-       num_vars = i;
-       for (free_number = 0; free_number < num_vars && found; free_number++) {
-               found = 0;
-               list_for_each(pos, boot_list) {
-                       boot = list_entry(pos, var_entry_t, list);
-                       if (boot->num == free_number) {
-                               found = 1;
-                               break;
-                       }
-               }
-               if (!found) break;
-       }
-       if (found && num_vars) free_number = vars[num_vars-1] + 1;
-       free(vars);
-       return free_number;
-}
-
-
-static void
-warn_duplicate_name(list_t *boot_list)
-{
-       list_t *pos;
-       var_entry_t *boot;
-       EFI_LOAD_OPTION *load_option;
-
-       list_for_each(pos, boot_list) {
-               boot = list_entry(pos, var_entry_t, list);
-               load_option = (EFI_LOAD_OPTION *)
-                       boot->var_data.Data;
-               if (!efichar_char_strcmp(opts.label,
-                                        load_option->description)) {
-                       fprintf(stderr, "** Warning ** : %.8s has same label %s\n",
-                              boot->name->d_name,
-                              opts.label);
-               }
-       }
-}
-
-
-static var_entry_t *
-make_boot_var(list_t *boot_list)
-{
-       var_entry_t *boot;
-       int free_number;
-       list_t *pos;
-
-       if (opts.bootnum == -1)
-               free_number = find_free_boot_var(boot_list);
-       else {
-               list_for_each(pos, boot_list) {
-                       boot = list_entry(pos, var_entry_t, list);
-                       if (boot->num == opts.bootnum) {
-                               fprintf(stderr, "** Warning ** : bootnum %04X "
-                                       "already exists\n", opts.bootnum);
-                               return NULL;
-                       }
-               }
-               free_number = opts.bootnum;
-       }
-
-       if (free_number == -1) return NULL;
-
-       /* Create a new var_entry_t object
-          and populate it.
-       */
-
-       boot = malloc(sizeof(*boot));
-       if (!boot) return NULL;
-       memset(boot, 0, sizeof(*boot));
-       boot->num = free_number;
-       if (!make_linux_efi_variable(&boot->var_data, free_number)) {
-               free(boot);
-               return NULL;
-       }
-       create_variable(&boot->var_data);
-       list_add_tail(&boot->list, boot_list);
-       return boot;
-}
-
-
-
-static efi_status_t
-read_boot(efi_variable_t *var, const char *name)
-{
-       char name_guid[PATH_MAX];
-
-       memset(var, 0, sizeof(*var));
-       fill_bootvar_name(name_guid, sizeof(name_guid), name);
-       return read_variable(name_guid, var);
-}
-
-static efi_status_t
-read_boot_order(efi_variable_t *boot_order)
-{
-       efi_status_t status;
-
-       status = read_boot(boot_order, "BootOrder");
-       if (status != EFI_SUCCESS && status != EFI_NOT_FOUND)
-               return status;
-
-       if (status == EFI_NOT_FOUND) {
-               fill_var(boot_order, "BootOrder");
-       }
-       return EFI_SUCCESS;
-}
-
-
-static efi_status_t
-add_to_boot_order(uint16_t num)
-{
-       efi_status_t status;
-       efi_variable_t boot_order;
-       uint64_t new_data_size;
-       uint16_t *new_data, *old_data;
-
-       status = read_boot_order(&boot_order);
-       if (status != EFI_SUCCESS) return status;
-
-       /* We've now got an array (in boot_order.Data) of the
-          boot order.  First add our entry, then copy the old array.
-       */
-       old_data = (uint16_t *)&(boot_order.Data);
-       new_data_size = boot_order.DataSize + sizeof(uint16_t);
-       new_data = malloc(new_data_size);
-
-       new_data[0] = num;
-       memcpy(new_data+1, old_data, boot_order.DataSize);
-
-       /* Now new_data has what we need */
-       memcpy(&(boot_order.Data), new_data, new_data_size);
-       boot_order.DataSize = new_data_size;
-       return create_or_edit_variable(&boot_order);
-}
-
-
-static efi_status_t
-remove_from_boot_order(uint16_t num)
-{
-       efi_status_t status;
-       efi_variable_t boot_order;
-       uint64_t new_data_size;
-       uint16_t *new_data, *old_data;
-       int old_i,new_i;
-       char boot_order_name[PATH_MAX];
-
-       status = read_boot_order(&boot_order);
-       if (status != EFI_SUCCESS) return status;
-       /* If it's empty, yea! */
-       if (!boot_order.DataSize) return EFI_SUCCESS;
-
-       fill_bootvar_name(boot_order_name, sizeof(boot_order_name),
-                         "BootOrder");
-
-       /* We've now got an array (in boot_order.Data) of the
-          boot order.  Simply copy the array, skipping the
-          entry we're deleting.
-       */
-       old_data = (uint16_t *)&(boot_order.Data);
-       /* Start with the same size */
-       new_data_size = boot_order.DataSize;
-       new_data = malloc(new_data_size);
-       for (old_i=0,new_i=0;
-            old_i < boot_order.DataSize / sizeof(uint16_t);
-            old_i++) {
-               if (old_data[old_i] != num) {
-                               /* Copy this value */
-                       new_data[new_i] = old_data[old_i];
-                       new_i++;
-               }
-       }
-
-       /* Now new_data has what we need */
-       new_data_size = new_i * sizeof(uint16_t);
-       memset(&(boot_order.Data), 0, boot_order.DataSize);
-       memcpy(&(boot_order.Data), new_data, new_data_size);
-       boot_order.DataSize = new_data_size;
-
-       return edit_variable(&boot_order);
-}
-
-static efi_status_t
-delete_var(const char *name)
-{
-       efi_variable_t var;
-
-       memset(&var, 0, sizeof(var));
-       fill_var(&var, name);
-       return delete_variable(&var);
-}
-
-static int
-read_boot_u16(const char *name)
-{
-       efi_status_t status;
-       efi_variable_t var;
-       uint16_t *n = (uint16_t *)(var.Data);
-
-       memset(&var, 0, sizeof(var));
-       status = read_boot(&var, name);
-       if (status) return -1;
-       return *n;
-}
-
-static efi_status_t
-set_boot_u16(const char *name, uint16_t num)
-{
-       efi_variable_t var;
-       uint16_t *n = (uint16_t *)var.Data;
-
-       memset(&var, 0, sizeof(var));
-
-       fill_var(&var, name);
-       *n = num;
-       var.DataSize = sizeof(uint16_t);
-       return create_or_edit_variable(&var);
-}
-
-static efi_status_t
-delete_boot_var(uint16_t num)
-{
-       efi_status_t status;
-       efi_variable_t var;
-       char name[16];
-       list_t *pos, *n;
-       var_entry_t *boot;
-
-       snprintf(name, sizeof(name), "Boot%04X", num);
-       memset(&var, 0, sizeof(var));
-       fill_var(&var, name);
-       status = delete_variable(&var);
-
-       /* For backwards compatibility, try to delete abcdef entries as well */
-       if (status) {
-               snprintf(name, sizeof(name), "Boot%04x", num);
-               memset(&var, 0, sizeof(var));
-               fill_var(&var, name);
-               status = delete_variable(&var);
-       }
-
-       if (status) return status;
-       list_for_each_safe(pos, n, &boot_entry_list) {
-               boot = list_entry(pos, var_entry_t, list);
-               if (boot->num == num) {
-                       status = remove_from_boot_order(num);
-                       if (status) return status;
-                       list_del(&(boot->list));
-                       break; /* short-circuit since it was found */
-               }
-       }
-       return EFI_SUCCESS;
-}
-
-
-static void
-set_var_nums(const char *pattern, list_t *list)
-{
-       list_t *pos;
-       var_entry_t *var;
-       int num=0, rc;
-       char *name;
-       int warn=0;
-
-       list_for_each(pos, list) {
-               var = list_entry(pos, var_entry_t, list);
-               rc = sscanf(var->name->d_name, pattern, &num);
-               if (rc == 1) {
-                       var->num = num;
-                       name = var->name->d_name; /* shorter name */
-                       if ((isalpha(name[4]) && islower(name[4])) ||
-                           (isalpha(name[5]) && islower(name[5])) ||
-                           (isalpha(name[6]) && islower(name[6])) ||
-                           (isalpha(name[7]) && islower(name[7]))) {
-                               fprintf(stderr, "** Warning ** : %.8s is not "
-                                       "EFI 1.10 compliant (lowercase hex in name)\n", name);
-                               warn++;
-                       }
-               }
-       }
-       if (warn) {
-               fprintf(stderr, "** Warning ** : please recreate these using efibootmgr to remove this warning.\n");
-       }
-}
-
-#if 0
-static efi_variable_t *
-find_pci_scsi_disk_blk(int fd, int bus, int device, int func,
-                      list_t *blk_list)
-{
-       list_t *pos;
-       int rc;
-       Scsi_Idlun idlun;
-       unsigned char host, channel, id, lun;
-       var_entry_t *blk;
-       efi_variable_t *blk_var;
-       long size = 0;
-
-       memset(&idlun, 0, sizeof(idlun));
-       rc = get_scsi_idlun(fd, &idlun);
-       if (rc) return NULL;
-
-       rc = disk_get_size(fd, &size);
-
-       idlun_to_components(&idlun, &host, &channel, &id, &lun);
-
-       list_for_each(pos, blk_list) {
-               blk = list_entry(pos, var_entry_t, list);
-               blk_var = blk->var_data;
-
-               if (!compare_pci_scsi_disk_blk(blk_var,
-                                              bus, device, func,
-                                              host, channel, id, lun,
-                                              0, size)) {
-                       return blk_var;
-               }
-       }
-       return NULL;
-}
-
-
-
-
-/* The right blkX variable contains:
-   1) the PCI and SCSI information for the disk passed in disk_name
-   2) Does not contain a partition field 
-*/
-
-
-static efi_variable_t *
-find_disk_blk(char *disk_name, list_t *blk_list)
-{
-       efi_variable_t *disk_blk = NULL;
-       int fd, rc;
-       unsigned char bus=0,device=0,func=0;
-       int interface_type=interface_type_unknown;
-       unsigned int controllernum=0, disknum=0;
-       unsigned char part=0;
-
-       fd = open(disk_name, O_RDONLY|O_DIRECT);
-       rc = disk_get_pci(fd, &bus, &device, &func);
-       if (rc) {
-               fprintf(stderr, "disk_get_pci() failed.\n");
-               return NULL;
-       }
-       rc = disk_info_from_fd(fd,
-                              &interface_type,
-                              &controllernum,
-                              &disknum,
-                              &part);
-       if (rc) {
-               fprintf(stderr, "disk_info_from_fd() failed.\n");
-               return NULL;
-       }
-       switch (interface_type)
-       {
-       case scsi:
-               return find_pci_scsi_disk_blk(fd,bus,device,func,blk_list);
-               break;
-       case ata:
-               return find_pci_ata_disk_blk(fd,bus,device,func,blk_list);
-               break;
-       case i2o:
-               return find_pci_i2o_disk_blk(fd,bus,device,func,blk_list);
-               break;
-       case md:
-               return find_pci_md_disk_blk(fd,bus,device,func,blk_list);
-               break;
-       default:
-               break;
-       }
-       return NULL;
-}
-#endif
-
-static void
-unparse_boot_order(uint16_t *order, int length)
-{
-       int i;
-       printf("BootOrder: ");
-       for (i=0; i<length; i++) {
-               printf("%04X", order[i]);
-               if (i < (length-1))
-                       printf(",");
-       }
-       printf("\n");
-}
-
-static int
-parse_boot_order(char *buffer, uint16_t *order, int length)
-{
-       int i;
-       int num, rc;
-
-       for (i=0; i<length && *buffer; i++) {
-               rc = sscanf(buffer, "%x", &num);
-               if (rc == 1) order[i] = num & 0xFFFF;
-               /* Advance to the comma */ 
-               while (*buffer && *buffer != ',') buffer++;
-               /* Advance through the comma(s) */
-               while (*buffer && *buffer == ',') buffer++;
-       }
-       return i;
-}
-
-static efi_status_t
-set_boot_order()
-{
-       efi_variable_t boot_order;
-       uint16_t *n = (uint16_t *)boot_order.Data;
-
-       if (!opts.bootorder) return EFI_SUCCESS;
-
-       memset(&boot_order, 0, sizeof(boot_order));
-       fill_var(&boot_order, "BootOrder");
-
-       boot_order.DataSize = parse_boot_order(opts.bootorder, n, 1024/sizeof(uint16_t)) * sizeof(uint16_t);
-       return create_or_edit_variable(&boot_order);
-}
-
-static void
-show_boot_vars()
-{
-       list_t *pos;
-       var_entry_t *boot;
-       char description[80];
-       EFI_LOAD_OPTION *load_option;
-       EFI_DEVICE_PATH *path;
-       char text_path[1024], *p;
-       unsigned long optional_data_len=0;
-
-       list_for_each(pos, &boot_entry_list) {
-               boot = list_entry(pos, var_entry_t, list);
-               load_option = (EFI_LOAD_OPTION *)
-                       boot->var_data.Data;
-               efichar_to_char(description,
-                               load_option->description, sizeof(description));
-               memset(text_path, 0, sizeof(text_path));
-               path = load_option_path(load_option);
-               if (boot->name)
-                       printf("%.8s", boot->name->d_name);
-               else
-                       printf("Boot%04X", boot->num);
-
-               if (load_option->attributes & LOAD_OPTION_ACTIVE)
-                       printf("* ");
-               else    printf("  ");
-               printf("%s", description);
-
-               if (opts.verbose) {
-                       unparse_path(text_path, path,
-                                    load_option->file_path_list_length);
-                       /* Print optional data */
-                       optional_data_len =
-                               boot->var_data.DataSize -
-                               load_option->file_path_list_length -
-                               ((char *)path - (char *)load_option);
-                       if (optional_data_len) {
-                               p = text_path;
-                               p += strlen(text_path);
-                               unparse_raw_text(p, ((uint8_t *)path) +
-                                                load_option->file_path_list_length,
-                                                optional_data_len);
-                       }
-
-                       printf("\t%s", text_path);
-               }
-               printf("\n");
-       }
-}
-
-
-
-static void
-show_boot_order()
-{
-       efi_status_t status;
-       efi_variable_t boot_order;
-       uint16_t *data;
-
-       status = read_boot_order(&boot_order);
-
-       if (status != EFI_SUCCESS) {
-               perror("show_boot_order()");
-               return;
-       }
-
-       /* We've now got an array (in boot_order.Data) of the
-          boot order.  First add our entry, then copy the old array.
-       */
-       data = (uint16_t *)&(boot_order.Data);
-       if (boot_order.DataSize)
-               unparse_boot_order(data, boot_order.DataSize / sizeof(uint16_t));
-
-}
-
-static efi_status_t
-set_active_state()
-{
-       list_t *pos;
-       var_entry_t *boot;
-       EFI_LOAD_OPTION *load_option;
-
-       list_for_each(pos, &boot_entry_list) {
-               boot = list_entry(pos, var_entry_t, list);
-               load_option = (EFI_LOAD_OPTION *)
-                       boot->var_data.Data;
-               if (boot->num == opts.bootnum) {
-                       if (opts.active == 1) {
-                               if (load_option->attributes
-                                   & LOAD_OPTION_ACTIVE) return EFI_SUCCESS;
-                               else {
-                                       load_option->attributes
-                                               |= LOAD_OPTION_ACTIVE;
-                                       return edit_variable(&boot->var_data);
-                               }
-                       }
-                       else if (opts.active == 0) {
-                               if (!(load_option->attributes
-                                     & LOAD_OPTION_ACTIVE))
-                                       return EFI_SUCCESS;
-                               else {
-                                       load_option->attributes
-                                               &= ~LOAD_OPTION_ACTIVE;
-                                       return edit_variable(&boot->var_data);
-                               }
-                       }
-               }
-       }
-       return EFI_SUCCESS;
-}
-
-
-
-
-static void
-usage()
-{
-       printf("efibootmgr version %s\n", EFIBOOTMGR_VERSION);
-       printf("usage: efibootmgr [options]\n");
-       printf("\t-a | --active         sets bootnum active\n");
-       printf("\t-A | --inactive       sets bootnum inactive\n");
-       printf("\t-b | --bootnum XXXX   modify BootXXXX (hex)\n");
-       printf("\t-B | --delete-bootnum delete bootnum (hex)\n");
-       printf("\t-c | --create         create new variable bootnum and add to bootorder\n");
-       printf("\t-d | --disk disk       (defaults to /dev/sda) containing loader\n");
-       printf("\t-e | --edd [1|3|-1]   force EDD 1.0 or 3.0 creation variables, or guess\n");
-       printf("\t-E | --device num      EDD 1.0 device number (defaults to 0x80)\n");
-       printf("\t-g | --gpt            force disk with invalid PMBR to be treated as GPT\n");
-       printf("\t-H | --acpi_hid XXXX  set the ACPI HID (used with -i)\n");
-       printf("\t-i | --iface name     create a netboot entry for the named interface\n");
-       printf("\t-l | --loader name     (defaults to \\elilo.efi)\n");
-       printf("\t-L | --label label     Boot manager display label (defaults to \"Linux\")\n");
-       printf("\t-n | --bootnext XXXX   set BootNext to XXXX (hex)\n");
-       printf("\t-N | --delete-bootnext delete BootNext\n");
-       printf("\t-o | --bootorder XXXX,YYYY,ZZZZ,...     explicitly set BootOrder (hex)\n");
-       printf("\t-O | --delete-bootorder delete BootOrder\n");
-       printf("\t-p | --part part        (defaults to 1) containing loader\n");
-       printf("\t-q | --quiet            be quiet\n");
-       printf("\t   | --test filename    don't write to NVRAM, write to filename.\n");
-       printf("\t-t | --timeout seconds  set boot manager timeout waiting for user input.\n");
-       printf("\t-T | --delete-timeout   delete Timeout.\n");
-       printf("\t-u | --unicode | --UCS-2  pass extra args as UCS-2 (default is ASCII)\n");
-       printf("\t-U | --acpi_uid XXXX    set the ACPI UID (used with -i)\n");
-       printf("\t-v | --verbose          print additional information\n");
-       printf("\t-V | --version          return version and exit\n");
-       printf("\t-w | --write-signature  write unique sig to MBR if needed\n");
-}
-
-static void
-set_default_opts()
-{
-       memset(&opts, 0, sizeof(opts));
-       opts.bootnum         = -1;   /* auto-detect */
-       opts.bootnext        = -1;   /* Don't set it */
-       opts.active          = -1;   /* Don't set it */
-       opts.timeout         = -1;   /* Don't set it */
-       opts.edd10_devicenum = 0x80;
-       opts.loader          = "\\elilo.efi";
-       opts.label           = "Linux";
-       opts.disk            = "/dev/sda";
-       opts.iface           = NULL;
-       opts.part            = 1;
-       opts.acpi_hid        = -1;
-       opts.acpi_uid        = -1;
-}
-
-static void
-parse_opts(int argc, char **argv)
-{
-       int c, num, rc;
-       int option_index = 0;
-
-       while (1)
-       {
-               static struct option long_options[] =
-                       /* name, has_arg, flag, val */
-               {
-                       {"active",                 no_argument, 0, 'a'},
-                       {"inactive",               no_argument, 0, 'A'},
-                       {"bootnum",          required_argument, 0, 'b'},
-                       {"delete-bootnum",         no_argument, 0, 'B'},
-                       {"create",                 no_argument, 0, 'c'},
-                       {"disk",             required_argument, 0, 'd'},
-                       {"iface",            required_argument, 0, 'i'},
-                       {"acpi_hid",         required_argument, 0, 'H'},
-                       {"edd-device",       required_argument, 0, 'E'},
-                       {"edd30",            required_argument, 0, 'e'},
-                       {"gpt",                    no_argument, 0, 'g'},
-                       {"loader",           required_argument, 0, 'l'},
-                       {"label",            required_argument, 0, 'L'},
-                       {"bootnext",         required_argument, 0, 'n'},
-                       {"delete-bootnext",        no_argument, 0, 'N'},
-                       {"bootorder",        required_argument, 0, 'o'},
-                       {"delete-bootorder",       no_argument, 0, 'O'},
-                       {"part",             required_argument, 0, 'p'},
-                       {"quiet",                  no_argument, 0, 'q'},
-                       {"test",             required_argument, 0,   1},
-                       {"timeout",          required_argument, 0, 't'},
-                       {"delete-timeout",         no_argument, 0, 'T'},
-                       {"unicode",                no_argument, 0, 'u'},
-                       {"UCS-2",                  no_argument, 0, 'u'},
-                       {"acpi_uid",         required_argument, 0, 'U'},
-                       {"verbose",          optional_argument, 0, 'v'},
-                       {"version",                no_argument, 0, 'V'},
-                       {"write-signature",        no_argument, 0, 'w'},
-                       {0, 0, 0, 0}
-               };
-
-               c = getopt_long (argc, argv,
-                                "AaBb:cd:e:E:gH:i:l:L:n:No:Op:qt:TuU:v::Vw",
-                                long_options, &option_index);
-               if (c == -1)
-                       break;
-
-               switch (c)
-               {
-               case 'a':
-                       opts.active = 1;
-                       break;
-               case 'A':
-                       opts.active = 0;
-                       break;
-               case 'B':
-                       opts.delete_boot = 1;
-                       break;
-               case 'b':
-                       rc = sscanf(optarg, "%X", &num);
-                       if (rc == 1) opts.bootnum = num;
-                       break;
-               case 'c':
-                       opts.create = 1;
-                       break;
-               case 'd':
-                       opts.disk = optarg;
-                       break;
-               case 'e':
-                       rc = sscanf(optarg, "%d", &num);
-                       if (rc == 1) opts.edd_version = num;
-                       break;
-               case 'E':
-                       rc = sscanf(optarg, "%x", &num);
-                       if (rc == 1) opts.edd10_devicenum = num;
-                       break;
-               case 'g':
-                       opts.forcegpt = 1;
-                       break;
-               case 'H':
-                       rc = sscanf(optarg, "%x", &num);
-                       if (rc == 1) opts.acpi_hid = num;
-                       break;
-               case 'i':
-                       opts.iface = optarg;
-                       break;
-               case 'l':
-                       opts.loader = optarg;
-                       break;
-               case 'L':
-                       opts.label = optarg;
-                       break;
-               case 'N':
-                       opts.delete_bootnext = 1;
-                       break;
-               case 'n':
-                       rc = sscanf(optarg, "%x", &num);
-                       if (rc == 1) opts.bootnext = num;
-                       break;
-               case 'o':
-                       opts.bootorder = optarg;
-                       break;
-               case 'O':
-                       opts.delete_bootorder = 1;
-                       break;
-               case 'p':
-                       rc = sscanf(optarg, "%u", &num);
-                       if (rc == 1) opts.part = num;
-                       break;
-               case 'q':
-                       opts.quiet = 1;
-                       break;
-               case 1:
-                       opts.testfile = optarg;
-                       break;
-               case 't':
-                       rc = sscanf(optarg, "%u", &num);
-                       if (rc == 1) {
-                               opts.timeout = num;
-                               opts.set_timeout = 1;
-                       }
-                       break;
-               case 'T':
-                       opts.delete_timeout = 1;
-                       break;
-               case 'u':
-                       opts.unicode = 1;
-                       break;
-
-               case 'U':
-                       rc = sscanf(optarg, "%x", &num);
-                       if (rc == 1) opts.acpi_uid = num;
-                       break;
-               case 'v':
-                       opts.verbose = 1;
-                       if (optarg) {
-                               if (!strcmp(optarg, "v"))  opts.verbose = 2;
-                               if (!strcmp(optarg, "vv")) opts.verbose = 3;
-                               rc = sscanf(optarg, "%d", &num);
-                               if (rc == 1)  opts.verbose = num;
-                       }
-                       break;
-               case 'V':
-                       opts.showversion = 1;
-                       break;
-
-               case 'w':
-                       opts.write_signature = 1;
-                       break;
-
-               default:
-                       usage();
-                       exit(1);
-               }
-       }
-
-       if (optind < argc) {
-               opts.argc = argc;
-               opts.argv = argv;
-               opts.optind = optind;
-       }
-}
-
-
-int
-main(int argc, char **argv)
-{
-       struct dirent  **boot_names = NULL;
-       var_entry_t *new_boot = NULL;
-       int num, num_boot_names=0;
-
-       set_default_opts();
-       parse_opts(argc, argv);
-       if (opts.showversion) {
-               printf("version %s\n", EFIBOOTMGR_VERSION);
-               return 0;
-       }
-
-       if (opts.iface && opts.acpi_hid == -1 && opts.acpi_uid == -1) {
-               fprintf(stderr, "\nYou must specify the ACPI HID and UID when using -i.\n\n");
-               return 1;
-       }
-
-       if (!opts.testfile)
-               set_fs_kernel_calls();
-
-       if (!opts.testfile) {
-               num_boot_names = read_boot_var_names(&boot_names);
-               read_vars(boot_names, num_boot_names, &boot_entry_list);
-               set_var_nums("Boot%04X-%*s", &boot_entry_list);
-
-               if (opts.delete_boot) {
-                       if (opts.bootnum == -1)
-                               fprintf(stderr, "\nYou must specify a boot entry to delete (see the -b option).\n\n");
-                       else
-                               delete_boot_var(opts.bootnum);
-               }
-
-               if (opts.active >= 0) {
-                       set_active_state();
-               }
-       }
-
-       if (opts.create) {
-               warn_duplicate_name(&boot_entry_list);
-               new_boot = make_boot_var(&boot_entry_list);
-               /* Put this boot var in the right BootOrder */
-               if (!opts.testfile && new_boot)
-                       add_to_boot_order(new_boot->num);
-       }
-
-       if (!opts.testfile) {
-
-               if (opts.delete_bootorder) {
-                       delete_var("BootOrder");
-               }
-
-               if (opts.bootorder) {
-                       set_boot_order();
-               }
-
-
-               if (opts.delete_bootnext) {
-                       delete_var("BootNext");
-               }
-
-               if (opts.delete_timeout) {
-                       delete_var("Timeout");
-               }
-
-               if (opts.bootnext >= 0) {
-                       set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
-               }
-
-               if (opts.set_timeout) {
-                       set_boot_u16("Timeout", opts.timeout);
-               }
-
-               if (!opts.quiet) {
-                       num = read_boot_u16("BootNext");
-                       if (num != -1 ) {
-                               printf("BootNext: %04X\n", num);
-                       }
-                       num = read_boot_u16("BootCurrent");
-                       if (num != -1) {
-                               printf("BootCurrent: %04X\n", num);
-                       }
-                       num = read_boot_u16("Timeout");
-                       if (num != -1) {
-                               printf("Timeout: %u seconds\n", num);
-                       }
-                       show_boot_order();
-                       show_boot_vars();
-               }
-       }
-       free_dirents(boot_names, num_boot_names);
-       free_vars(&boot_entry_list);
-       return 0;
-}
-
index dac4907e8b486a718e2da313abcceb048f8ddb72..790e2e4bb206ae97f09045107404163b5e4eb80d 100644 (file)
@@ -11,7 +11,7 @@ efibootmgr_LIBS    := crc32.o disk.o efi.o efichar.o gpt.o scsi_ioctls.o \
 efibootmgr_LIBDIR  := src/lib
 efibootmgr_FULLLIB := \
        $(patsubst %,$(efibootmgr_LIBDIR)/%,$(efibootmgr_LIBS))
-LIBS = -lpci
+LIBS = -lpci -lz
 
 ALLDEPS += $(efibootmgr_FULLTARGET)
 CLEANLIST += $(efibootmgr_FULLTARGET)
@@ -20,5 +20,5 @@ bindir_TARGETS += $(efibootmgr_FULLTARGET)
 
 $(efibootmgr_FULLTARGET): \
        $(efibootmgr_FULLOBJECT) \
-       $(efibootmgr_FULLLIB) \
-       $(LIBS)
+       $(efibootmgr_FULLLIB)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(efibootmgr_SRCDIR)/efibootmgr.c $^ $(LIBS) -o $@
index a760eb185b70f209f7d1b733ad7f847053591144..a4ce5cfe21cdd6fe8ea942cd133f05dba025bddb 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <linux/sockios.h>
+#include <linux/types.h>
 #include <net/if.h>
 #include <pci/pci.h>
 #include <asm/types.h>
@@ -721,7 +722,7 @@ append_extra_args_file(void *data, unsigned long maxchars)
 
        if (fd == -1) {
                perror("Failed to open extra arguments file");
-               return 0;
+               exit(1);
        }
 
        do {
diff --git a/src/lib/efi.c.orig b/src/lib/efi.c.orig
deleted file mode 100644 (file)
index 2257e9f..0000000
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
-  efivars_proc.[ch] - Manipulates EFI variables as exported in /proc/efi/vars
-
-  Copyright (C) 2001,2003 Dell Computer Corporation <Matt_Domsch@dell.com>
-
-    This program 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 2 of the License, or
-    (at your option) any later version.
-
-    This program 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 this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <linux/sockios.h>
-#include <net/if.h>
-#include <pci/pci.h>
-#include <linux/ethtool.h>
-#include "efi.h"
-#include "efichar.h"
-#include "scsi_ioctls.h"
-#include "disk.h"
-#include "efibootmgr.h"
-#include "efivars_procfs.h"
-#include "efivars_sysfs.h"
-#include "list.h"
-
-static struct efivar_kernel_calls *fs_kernel_calls;
-
-EFI_DEVICE_PATH *
-load_option_path(EFI_LOAD_OPTION *option)
-{
-       char *p = (char *) option;
-       return (EFI_DEVICE_PATH *)
-               (p + sizeof(uint32_t) /* Attributes */
-                + sizeof(uint16_t)   /* FilePathListLength*/
-                + efichar_strsize(option->description)); /* Description */
-}
-
-char *
-efi_guid_unparse(efi_guid_t *guid, char *out)
-{
-       sprintf(out, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-               guid->b[3], guid->b[2], guid->b[1], guid->b[0],
-               guid->b[5], guid->b[4], guid->b[7], guid->b[6],
-               guid->b[8], guid->b[9], guid->b[10], guid->b[11],
-               guid->b[12], guid->b[13], guid->b[14], guid->b[15]);
-        return out;
-}
-
-void
-set_fs_kernel_calls()
-{
-       char name[PATH_MAX];
-       DIR *dir;
-       snprintf(name, PATH_MAX, "%s", SYSFS_DIR_EFI_VARS);
-       dir = opendir(name);
-       if (dir) {
-               closedir(dir);
-               fs_kernel_calls = &sysfs_kernel_calls;
-               return;
-       }
-
-       snprintf(name, PATH_MAX, "%s", PROCFS_DIR_EFI_VARS);
-       dir = opendir(name);
-       if (dir) {
-               closedir(dir);
-               fs_kernel_calls = &procfs_kernel_calls;
-               return;
-       }
-       fprintf(stderr, "Fatal: Couldn't open either sysfs or procfs directories for accessing EFI variables.\n");
-       fprintf(stderr, "Try 'modprobe efivars' as root.\n");
-       exit(1);
-}
-
-
-
-static efi_status_t
-write_variable_to_file(efi_variable_t *var)
-{
-       int fd, byteswritten;
-       if (!var || !opts.testfile) return EFI_INVALID_PARAMETER;
-
-       printf("Test mode: Writing to %s\n", opts.testfile);
-       fd = creat(opts.testfile, S_IRWXU);
-       if (fd == -1) {
-               perror("Couldn't write to testfile");
-               return EFI_INVALID_PARAMETER;
-       }
-
-       byteswritten = write(fd, var, sizeof(*var));
-       if (byteswritten == -1) {
-               perror("Writing to testfile");
-
-       }
-       close(fd);
-       return EFI_SUCCESS;
-}
-
-efi_status_t
-read_variable(const char *name, efi_variable_t *var)
-{
-       if (!name || !var) return EFI_INVALID_PARAMETER;
-       return fs_kernel_calls->read(name, var);
-}
-
-efi_status_t
-create_variable(efi_variable_t *var)
-{
-       if (!var) return EFI_INVALID_PARAMETER;
-       if (opts.testfile) return write_variable_to_file(var);
-       return fs_kernel_calls->create(var);
-}
-
-efi_status_t
-delete_variable(efi_variable_t *var)
-{
-       if (!var) return EFI_INVALID_PARAMETER;
-       if (opts.testfile) return write_variable_to_file(var);
-       return fs_kernel_calls->delete(var);
-}
-
-
-efi_status_t
-edit_variable(efi_variable_t *var)
-{
-       char name[PATH_MAX];
-       if (!var) return EFI_INVALID_PARAMETER;
-       if (opts.testfile) return write_variable_to_file(var);
-
-       variable_to_name(var, name);
-       return fs_kernel_calls->edit(name, var);
-}
-
-efi_status_t
-create_or_edit_variable(efi_variable_t *var)
-{
-       efi_variable_t testvar;
-       char name[PATH_MAX];
-
-       memcpy(&testvar, var, sizeof(*var));
-       variable_to_name(var, name);
-
-       if (read_variable(name, &testvar) == EFI_SUCCESS)
-               return edit_variable(var);
-       else
-               return create_variable(var);
-}
-
-static int
-select_boot_var_names(const struct dirent *d)
-{
-       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
-read_boot_var_names(struct dirent ***namelist)
-{
-       if (!fs_kernel_calls || !namelist) return -1;
-       return scandir(fs_kernel_calls->path,
-                      namelist, select_boot_var_names,
-                      alphasort);
-}
-
-
-static int
-get_edd_version()
-{
-       efi_status_t status;
-       efi_variable_t var;
-       efi_guid_t guid = BLKX_UNKNOWN_GUID;
-       char name[80], text_guid[40];
-       ACPI_DEVICE_PATH *path = (ACPI_DEVICE_PATH *)&(var.Data);
-       int rc = 0;
-
-       /* Allow global user option override */
-
-       switch (opts.edd_version)
-       {
-       case 0: /* No EDD information */
-               return 0;
-               break;
-       case 1: /* EDD 1.0 */
-               return 1;
-               break;
-       case 3: /* EDD 3.0 */
-               return 3;
-               break;
-       default:
-               break;
-       }
-
-
-       memset(&var, 0, sizeof(efi_variable_t));
-       efi_guid_unparse(&guid, text_guid);
-       sprintf(name, "blk0-%s", text_guid);
-
-       status = read_variable(name, &var);
-       if (status != EFI_SUCCESS) {
-               return 0;
-       }
-       if (path->type == 2 && path->subtype == 1) rc = 3;
-       else rc = 1;
-       return rc;
-}
-
-/*
-  EFI_DEVICE_PATH, 0x01 (Hardware), 0x04 (Vendor), length 0x0018
-  This needs to know what EFI device has the boot device.
-*/
-static uint16_t
-make_edd10_device_path(void *dest, uint32_t hardware_device)
-{
-       VENDOR_DEVICE_PATH *hw;
-       char buffer[EDD10_HARDWARE_VENDOR_PATH_LENGTH];
-       efi_guid_t guid = EDD10_HARDWARE_VENDOR_PATH_GUID;
-       uint32_t *data;
-       memset(buffer, 0, sizeof(buffer));
-       hw = (VENDOR_DEVICE_PATH *)buffer;
-       data = (uint32_t *)hw->data;
-       hw->type = 0x01; /* Hardware Device Path */
-       hw->subtype = 0x04; /* Vendor */
-       hw->length = EDD10_HARDWARE_VENDOR_PATH_LENGTH;
-       memcpy(&(hw->vendor_guid), &guid, sizeof(guid));
-       *data = hardware_device;
-       memcpy(dest, buffer, hw->length);
-       return hw->length;
-}
-
-static uint16_t
-make_end_device_path(void *dest)
-{
-       END_DEVICE_PATH p;
-       memset(&p, 0, sizeof(p));
-       p.type = 0x7F; /* End of Hardware Device Path */
-       p.subtype = 0xFF; /* End Entire Device Path */
-       p.length = sizeof(p);
-       memcpy(dest, &p, p.length);
-       return p.length;
-}
-
-static uint16_t
-make_acpi_device_path(void *dest, uint32_t _HID, uint32_t _UID)
-{
-       ACPI_DEVICE_PATH p;
-       memset(&p, 0, sizeof(p));
-       p.type = 2;
-       p.subtype = 1;
-       p.length = sizeof(p);
-       p._HID = _HID;
-       p._UID = _UID;
-       memcpy(dest, &p, p.length);
-       return p.length;
-}
-
-static uint16_t
-make_mac_addr_device_path(void *dest, char *mac, uint8_t iftype)
-{
-
-        int i;
-       MAC_ADDR_DEVICE_PATH p;
-       memset(&p, 0, sizeof(p));
-       p.type = 3;
-       p.subtype = 11;
-       p.length = sizeof(p);
-       for (i=0; i < 14; i++) {
-               p.macaddr[i] = mac[i];
-       }
-       p.iftype = iftype;
-       memcpy(dest, &p, p.length);
-       return p.length;
-}
-
-struct device
-{
-       struct pci_dev *pci_dev;
-       struct list_head node;
-};
-
-static struct device *
-is_parent_bridge(struct pci_dev *p, unsigned int target_bus)
-{
-       struct device *d;
-       unsigned int primary, secondary;
-
-       if ( (pci_read_word(p, PCI_HEADER_TYPE) & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
-               return NULL;
-
-       primary=pci_read_byte(p, PCI_PRIMARY_BUS);
-       secondary=pci_read_byte(p, PCI_SECONDARY_BUS);
-
-
-       if (secondary != target_bus)
-               return NULL;
-
-       d = malloc(sizeof(struct device));
-       if (!d)
-               return NULL;
-       memset(d, 0, sizeof(*d));
-       INIT_LIST_HEAD(&d->node);
-
-       d->pci_dev = p;
-
-       return d;
-}
-
-static struct device *
-find_parent(struct pci_access *pacc, unsigned int target_bus)
-{
-       struct device *dev;
-       struct pci_dev *p;
-
-       for (p=pacc->devices; p; p=p->next) {
-               dev = is_parent_bridge(p, target_bus);
-               if (dev)
-                       return dev;
-       }
-       return NULL;
-}
-
-static uint16_t
-make_one_pci_device_path(void *dest, uint8_t device, uint8_t function)
-{
-       PCI_DEVICE_PATH p;
-       memset(&p, 0, sizeof(p));
-       p.type = 1;
-       p.subtype = 1;
-       p.length   = sizeof(p);
-       p.device   = device;
-       p.function = function;
-       memcpy(dest, &p, p.length);
-       return p.length;
-}
-
-static uint16_t
-make_pci_device_path(void *dest, uint8_t bus, uint8_t device, uint8_t function)
-{
-       struct device *dev;
-       struct pci_access *pacc;
-       struct list_head *pos, *n;
-       LIST_HEAD(pci_parent_list);
-       char *p = dest;
-
-       pacc = pci_alloc();
-       if (!pacc)
-               return 0;
-
-       pci_init(pacc);
-       pci_scan_bus(pacc);
-
-       do {
-               dev = find_parent(pacc, bus);
-               if (dev) {
-                       list_add(&pci_parent_list, &dev->node);
-                       bus = dev->pci_dev->bus;
-               }
-       } while (dev && bus);
-
-
-       list_for_each_safe(pos, n, &pci_parent_list) {
-               dev = list_entry(pos, struct device, node);
-               p += make_one_pci_device_path(p,
-                                             dev->pci_dev->dev,
-                                             dev->pci_dev->func);
-               list_del(&dev->node);
-               free(dev);
-       }
-
-       p += make_one_pci_device_path(p, device, function);
-
-       pci_cleanup(pacc);
-
-       return ((void *)p - dest);
-}
-
-static uint16_t
-make_scsi_device_path(void *dest, uint16_t id, uint16_t lun)
-{
-       SCSI_DEVICE_PATH p;
-       memset(&p, 0, sizeof(p));
-       p.type = 3;
-       p.subtype = 2;
-       p.length   = sizeof(p);
-       p.id       = id;
-       p.lun      = lun;
-       memcpy(dest, &p, p.length);
-       return p.length;
-}
-
-static uint16_t
-make_harddrive_device_path(void *dest, uint32_t num, uint64_t start, uint64_t size,
-                          uint8_t *signature,
-                          uint8_t mbr_type, uint8_t signature_type)
-{
-       HARDDRIVE_DEVICE_PATH p;
-       memset(&p, 0, sizeof(p));
-       p.type = 4;
-       p.subtype = 1;
-       p.length   = sizeof(p);
-       p.part_num = num;
-       p.start = start;
-       p.size = size;
-       if (signature) memcpy(p.signature, signature, 16);
-       p.mbr_type = mbr_type;
-       p.signature_type = signature_type;
-       memcpy(dest, &p, p.length);
-       return p.length;
-}
-
-static uint16_t
-make_file_path_device_path(void *dest, efi_char16_t *name)
-{
-       FILE_PATH_DEVICE_PATH *p;
-       char buffer[1024];
-       int namelen  = efichar_strlen(name, -1);
-       int namesize = efichar_strsize(name);
-
-       memset(buffer, 0, sizeof(buffer));
-       p = (FILE_PATH_DEVICE_PATH *)buffer;
-       p->type      = 4;
-       p->subtype   = 4;
-       p->length    = 4 + namesize;
-       efichar_strncpy(p->path_name,
-                       name, namelen);
-
-       memcpy(dest, buffer, p->length);
-       return p->length;
-
-}
-
-
-
-static long
-make_edd30_device_path(int fd, void *buffer)
-{
-       int rc=0;
-       unsigned char bus=0, device=0, function=0;
-       Scsi_Idlun idlun;
-       unsigned char host=0, channel=0, id=0, lun=0;
-       char *p = buffer;
-
-
-       rc = disk_get_pci(fd, &bus, &device, &function);
-       if (rc) return 0;
-
-       memset(&idlun, 0, sizeof(idlun));
-       rc = get_scsi_idlun(fd, &idlun);
-       if (rc) return 0;
-       idlun_to_components(&idlun, &host, &channel, &id, &lun);
-
-       p += make_acpi_device_path      (p, EISAID_PNP0A03, bus);
-       p += make_pci_device_path       (p, bus, device, function);
-       p += make_scsi_device_path      (p, id, lun);
-       return ((void *)p - buffer);
-}
-
-/**
- * make_disk_load_option()
- * @disk disk
- *
- * Returns 0 on error, length of load option created on success.
- */
-char *make_disk_load_option(char *p, char *disk)
-{
-    int disk_fd=0;
-    char buffer[80];
-    char signature[16];
-    int rc, edd_version=0;
-    uint8_t mbr_type=0, signature_type=0;
-    uint64_t start=0, size=0;
-    efi_char16_t os_loader_path[40];
-
-    memset(signature, 0, sizeof(signature));
-
-    disk_fd = open(opts.disk, O_RDWR);
-    if (disk_fd == -1) {
-        sprintf(buffer, "Could not open disk %s", opts.disk);
-       perror(buffer);
-       return 0;
-    }
-
-    if (opts.edd_version) {
-        edd_version = get_edd_version();
-
-       if (edd_version == 3) {
-           p += make_edd30_device_path(disk_fd, p);
-       }
-       else if (edd_version == 1) {
-           p += make_edd10_device_path(p, opts.edd10_devicenum);
-       }
-    }
-
-    rc = disk_get_partition_info (disk_fd, opts.part,
-                                 &start, &size, signature,
-                                 &mbr_type, &signature_type);
-
-    close(disk_fd);
-
-    if (rc) {
-        fprintf(stderr, "Error: no partition information on disk %s.\n"
-               "       Cowardly refusing to create a boot option.\n",
-               opts.disk);
-       return 0;
-    }
-
-    p += make_harddrive_device_path (p, opts.part,
-                                    start, size,
-                                    signature,
-                                    mbr_type, signature_type);
-
-    efichar_from_char(os_loader_path, opts.loader, sizeof(os_loader_path));
-    p += make_file_path_device_path (p, os_loader_path);
-    p += make_end_device_path       (p);
-
-    return(p);
-}
-
-/**
- * make_net_load_option()
- * @data - load option returned
- *
- * Returns NULL on error, or p advanced by length of load option
- * created on success.
- */
-char *make_net_load_option(char *p, char *iface)
-{
-    /* copied pretty much verbatim from the ethtool source */
-    int fd = 0, err; 
-    int bus, slot, func;
-    struct ifreq ifr;
-    struct ethtool_drvinfo drvinfo;
-
-    memset(&ifr, 0, sizeof(ifr));
-    strcpy(ifr.ifr_name, iface);
-    drvinfo.cmd = ETHTOOL_GDRVINFO;
-    ifr.ifr_data = (caddr_t)&drvinfo;
-    /* Open control socket */
-    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;
-    }
-
-    /* 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;
-           }
-    }
-
-    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;
-}
-
-/**
- * make_linux_load_option()
- * @data - load option returned
- *
- * Returns 0 on error, length of load option created on success.
- */
-static unsigned long
-make_linux_load_option(void *data)
-{
-       EFI_LOAD_OPTION *load_option = data;
-       char *p = data, *q;
-       efi_char16_t description[64];
-       unsigned long datasize=0;
-
-       /* Write Attributes */
-       if (opts.active) load_option->attributes = LOAD_OPTION_ACTIVE;
-       else             load_option->attributes = 0;
-
-       p += sizeof(uint32_t);
-       /* skip writing file_path_list_length */
-       p += sizeof(uint16_t);
-       /* Write description.  This is the text that appears on the screen for the load option. */
-       memset(description, 0, sizeof(description));
-       efichar_from_char(description, opts.label, sizeof(description));
-       efichar_strncpy(load_option->description, description, sizeof(description));
-       p += efichar_strsize(load_option->description);
-
-       q = p;
-
-       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;
-
-       datasize = (uint8_t *)p - (uint8_t *)data;
-       return datasize;
-}
-
-/*
- * append_extra_args()
- * appends all arguments from argv[] not snarfed by getopt
- * as one long string onto data, up to maxchars.  allow for nulls
- */
-
-static unsigned long
-append_extra_args_ascii(void *data, unsigned long maxchars)
-{
-       char *p = data;
-       int i, appended=0;
-       unsigned long usedchars=0;
-       if (!data) return 0;
-
-
-       for (i=opts.optind; i < opts.argc && usedchars < maxchars; i++) {
-               p = strncpy(p, opts.argv[i], maxchars-usedchars-1);
-               p += strlen(p);
-               appended=1;
-
-               usedchars = p - (char *)data;
-
-               /* Put a space between args */
-               if (i < (opts.argc-1)) {
-
-                       p = strncpy(p, " ", maxchars-usedchars-1);
-                       p += strlen(p);
-                       usedchars = p - (char *)data;
-               }
-
-       }
-       /* Remember the NULL */
-       if (appended) return strlen(data) + 1;
-       return 0;
-}
-
-static unsigned long
-append_extra_args_unicode(void *data, unsigned long maxchars)
-{
-       char *p = data;
-       int i, appended=0;
-       unsigned long usedchars=0;
-       if (!data) return 0;
-
-
-       for (i=opts.optind; i < opts.argc && usedchars < maxchars; i++) {
-               p += efichar_from_char((efi_char16_t *)p, opts.argv[i],
-                                      maxchars-usedchars);
-               usedchars = efichar_strsize(data) - sizeof(efi_char16_t);
-               appended=1;
-
-               /* Put a space between args */
-               if (i < (opts.argc-1)) {
-                       p += efichar_from_char((efi_char16_t *)p, " ",
-                                              maxchars-usedchars);
-                       usedchars = efichar_strsize(data) -
-                               sizeof(efi_char16_t);
-               }
-       }
-
-       if (appended) return efichar_strsize( (efi_char16_t *)data );
-       return 0;
-}
-
-
-static unsigned long
-append_extra_args(void *data, unsigned long maxchars)
-{
-       if (opts.unicode)
-         return append_extra_args_unicode(data, maxchars);
-       else
-         return append_extra_args_ascii(data, maxchars);
-}
-
-
-
-int
-make_linux_efi_variable(efi_variable_t *var,
-                       unsigned int free_number)
-{
-       efi_guid_t guid = EFI_GLOBAL_VARIABLE;
-       char buffer[16];
-       unsigned char *optional_data=NULL;
-       unsigned long load_option_size = 0, opt_data_size=0;
-
-       memset(buffer,    0, sizeof(buffer));
-
-       /* VariableName needs to be BootXXXX */
-       sprintf(buffer, "Boot%04X", free_number);
-
-       efichar_from_char(var->VariableName, buffer, 1024);
-
-       memcpy(&(var->VendorGuid), &guid, sizeof(guid));
-       var->Attributes =
-               EFI_VARIABLE_NON_VOLATILE |
-               EFI_VARIABLE_BOOTSERVICE_ACCESS |
-               EFI_VARIABLE_RUNTIME_ACCESS;
-
-       /* Set Data[] and DataSize */
-
-       load_option_size =  make_linux_load_option(var->Data);
-
-       if (!load_option_size) return 0;
-
-       /* Set OptionalData (passed as binary to the called app) */
-       optional_data = var->Data + load_option_size;
-       opt_data_size = append_extra_args(optional_data,
-                                 sizeof(var->Data) - load_option_size);
-       var->DataSize = load_option_size + opt_data_size;
-       return var->DataSize;
-}
-
-
-int
-variable_to_name(efi_variable_t *var, char *name)
-{
-       char *p = name;
-       efichar_to_char(p, var->VariableName, PATH_MAX);
-       p += strlen(p);
-       p += sprintf(p, "-");
-       efi_guid_unparse(&var->VendorGuid, p);
-       return strlen(name);
-}
index 02985f44c5509f78f92743ac69b700c9d3cf048e..d90ddaf235c072ffe3626c0f358345f1042a59d9 100644 (file)
@@ -624,9 +624,8 @@ gpt_disk_get_partition_info(int fd,
                memcpy(signature, &p->unique_partition_guid,
                       sizeof (p->unique_partition_guid));
        } else {
-               *start = 0;
-               *size = last_lba(fd) + 1;
-               memcpy(signature, &gpt->disk_guid, sizeof (gpt->disk_guid));
+               fprintf (stderr,"partition %d is not valid\n", num);
+               return 1;
        }
        return 0;
 }
index 3c28f1c870a302a7a09f20ff14fd961d13da04ed..d123ae6aaaa5c8a22885da1fe8c65cbde471a7f3 100644 (file)
@@ -32,7 +32,8 @@
 #include "unparse_path.h"
 #include "efichar.h"
 
-
+/* Avoid unaligned access warnings */
+#define get(buf, obj) *(typeof(obj) *)memcpy(buf, &obj, sizeof(obj))
 
 
 void
@@ -72,12 +73,11 @@ dump_raw_data(void *data, uint64_t length)
 unsigned long
 unparse_raw(char *buffer, uint8_t *p, uint64_t length)
 {
-       uint64_t i; unsigned char c;
+       uint64_t i;
+       char a[1];
        char *q = buffer;
        for (i=0; i<length; i++) {
-               c = p[i];
-               //if (c < 32 || c > 127) c = '.';
-               q += sprintf(q, "%02x", c);
+               q += sprintf(q, "%02x", get(a, p[i]));
        }
        return q - buffer;
 }
@@ -112,10 +112,11 @@ static int
 unparse_acpi_path(char *buffer, EFI_DEVICE_PATH *path)
 {
        ACPI_DEVICE_PATH *acpi = (ACPI_DEVICE_PATH *)path;
+       char a[16], b[16];
 
        switch (path->subtype) {
        case 1:
-               return sprintf(buffer, "ACPI(%x,%x)", acpi->_HID, acpi->_UID);
+               return sprintf(buffer, "ACPI(%x,%x)", get(a, acpi->_HID), get(b, acpi->_UID));
                break;
        default:
                return unparse_raw(buffer, (uint8_t *)path, path->length);
@@ -127,7 +128,8 @@ unparse_acpi_path(char *buffer, EFI_DEVICE_PATH *path)
 static int
 unparse_vendor_path(char *buffer, VENDOR_DEVICE_PATH *path)
 {
-       char text_guid[40], *p = buffer, *q = (uint8_t *)path + 20;
+       char text_guid[40], *p = buffer;
+       unsigned char *q = (uint8_t *)path + 20;
        efi_guid_unparse(&path->vendor_guid, text_guid);
        p += sprintf(p, "Vendor(%s,", text_guid);
        p += unparse_raw(p, q, path->length - 20);
@@ -142,26 +144,27 @@ unparse_hardware_path(char *buffer, EFI_DEVICE_PATH *path)
        PCCARD_DEVICE_PATH *pccard = (PCCARD_DEVICE_PATH *)path;
        MEMORY_MAPPED_DEVICE_PATH *mm = (MEMORY_MAPPED_DEVICE_PATH *)path;
        CONTROLLER_DEVICE_PATH *ctlr = (CONTROLLER_DEVICE_PATH *)path;
+       char a[16], b[16], c[16];
 
        switch (path->subtype) {
        case 1:
-               return sprintf(buffer, "PCI(%x,%x)",
-                              pci->device, pci->function);
+               return sprintf(buffer, "PCI(%x,%x)", get(a, pci->device), get(b, pci->function));
                break;
        case 2:
-               return sprintf(buffer, "PCCARD(%x)", pccard->socket);
+               return sprintf(buffer, "PCCARD(%x)", get(a, pccard->socket));
                break;
        case 3:
                return sprintf(buffer, "MM(%x,%" PRIx64 ",%" PRIx64 ")",
-                              mm->memory_type,
-                              mm->start, mm->end);
+                              get(a, mm->memory_type),
+                              get(b, mm->start),
+                              get(c, mm->end));
                break;
        case 4:
                return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path);
                break;
 
        case 5:
-               return sprintf(buffer, "Controller(%x)", ctlr->controller);
+               return sprintf(buffer, "Controller(%x)", get(a, ctlr->controller));
                break;
 
        default:
@@ -185,33 +188,35 @@ unparse_messaging_path(char *buffer, EFI_DEVICE_PATH *path)
        IPv4_DEVICE_PATH *ipv4 = (IPv4_DEVICE_PATH *)path;
 /*     IPv6_DEVICE_PATH *ipv6 = (IPv6_DEVICE_PATH *)path; */
        char *p = buffer;
+       char a[16], b[16], c[16], d[16], e[16];
 
        switch (path->subtype) {
        case 1:
                return sprintf(buffer, "ATAPI(%x,%x,%x)",
-                              atapi->primary_secondary,
-                              atapi->slave_master, atapi->lun);
+                              get(a, atapi->primary_secondary),
+                              get(b, atapi->slave_master),
+                              get(c, atapi->lun));
                break;
        case 2:
-               return sprintf(buffer, "SCSI(%x,%x)", scsi->id, scsi->lun);
+               return sprintf(buffer, "SCSI(%x,%x)", get(a, scsi->id), get(b, scsi->lun));
                break;
 
        case 3:
-               return sprintf(buffer, "FC(%" PRIx64 ",%" PRIx64 ")", fc->wwn, fc->lun);
+               return sprintf(buffer, "FC(%" PRIx64 ",%" PRIx64 ")", get(a, fc->wwn), get(b, fc->lun));
                break;
        case 4:
-               return sprintf(buffer, "1394(%" PRIx64 ")", i1394->guid);
+               return sprintf(buffer, "1394(%" PRIx64 ")", get(a, i1394->guid));
                break;
        case 5:
-               return sprintf(buffer, "USB(%x,%x)", usb->port, usb->endpoint);
+               return sprintf(buffer, "USB(%x,%x)", get(a, usb->port), get(b, usb->endpoint));
                break;
        case 6:
-               return sprintf(buffer, "I2O(%x)", i2o->tid);
+               return sprintf(buffer, "I2O(%x)", get(a, i2o->tid));
                break;
        case 11:
                p += sprintf(p, "MAC(");
                p += unparse_raw(p, mac->macaddr, 6);
-               p += sprintf(p, ",%hhx)", mac->iftype);
+               p += sprintf(p, ",%hhx)", get(a, mac->iftype));
                return (int) (p - buffer);
                break;
        case 12:
@@ -219,15 +224,15 @@ unparse_messaging_path(char *buffer, EFI_DEVICE_PATH *path)
                p += unparse_ipv4_port(p, ipv4->local_ip, ipv4->local_port);
                p += sprintf(p, "<->");
                p += unparse_ipv4_port(p, ipv4->remote_ip, ipv4->remote_port);
-               p += sprintf(p, ",%hx, %hhx", ipv4->protocol, ipv4->static_addr);
+               p += sprintf(p, ",%hx, %hhx", get(a, ipv4->protocol), get(b, ipv4->static_addr));
                return (int) (p - buffer);
                break;
 
        case 15:
                return sprintf(buffer, "USBClass(%hx,%hx,%hhx,%hhx,%hhx)",
-                              usbclass->vendor, usbclass->product,
-                              usbclass->class, usbclass->subclass,
-                              usbclass->protocol);
+                              get(a, usbclass->vendor), get(b, usbclass->product),
+                              get(c, usbclass->class), get(d, usbclass->subclass),
+                              get(e, usbclass->protocol));
                break;
        default:
                return unparse_raw(buffer, (uint8_t *)path, path->length);
@@ -241,13 +246,15 @@ unparse_media_hard_drive_path(char *buffer, EFI_DEVICE_PATH *path)
 {
        HARDDRIVE_DEVICE_PATH *hd = (HARDDRIVE_DEVICE_PATH *)path;
        char text_uuid[40], *sig=text_uuid;
+       char a[16], b[16], c[16];
        
        switch (hd->signature_type) {
        case 0x00:
                sprintf(sig, "None");
                break;
        case 0x01:
-               sprintf(sig, "%08x", *(uint32_t *)hd->signature);
+               sprintf(sig, "%08x", *(uint32_t *)memcpy(a, &hd->signature,
+                                                        sizeof(hd->signature)));
                break;
        case 0x02: /* GPT */
                 efi_guid_unparse((efi_guid_t *)hd->signature, sig);
@@ -257,7 +264,10 @@ unparse_media_hard_drive_path(char *buffer, EFI_DEVICE_PATH *path)
        }
 
        return sprintf(buffer, "HD(%x,%" PRIx64 ",%" PRIx64 ",%s)",
-                      hd->part_num, hd->start, hd->size, sig);
+                      get(a, hd->part_num),
+                      get(b, hd->start),
+                      get(c, hd->size),
+                      sig);
 }
 
 
@@ -272,6 +282,7 @@ unparse_media_path(char *buffer, EFI_DEVICE_PATH *path)
        char text_guid[40], *p = buffer;
        char file_name[80];
        memset(file_name, 0, sizeof(file_name));
+       char a[16], b[16], c[16];
 
        switch (path->subtype) {
        case 1:
@@ -279,7 +290,7 @@ unparse_media_path(char *buffer, EFI_DEVICE_PATH *path)
                break;
        case 2:
                return sprintf(buffer, "CD-ROM(%x,%" PRIx64 ",%" PRIx64 ")",
-                              cdrom->boot_entry, cdrom->start, cdrom->size);
+                              get(a, cdrom->boot_entry), get(b, cdrom->start), get(c, cdrom->size));
                break;
        case 3:
                return unparse_vendor_path(buffer, (VENDOR_DEVICE_PATH *)path);
@@ -302,9 +313,11 @@ static int
 unparse_bios_path(char *buffer, EFI_DEVICE_PATH *path)
 {
        BIOS_BOOT_SPEC_DEVICE_PATH *bios = (BIOS_BOOT_SPEC_DEVICE_PATH *)path;
-       char *p = buffer, *q = (uint8_t *)path + 8;
+       char *p = buffer;
+       unsigned char *q = (uint8_t *)path + 8;
+       char a[16], b[16];
        p += sprintf(p, "BIOS(%x,%x,",
-                    bios->device_type, bios->status_flag);
+                    get(a, bios->device_type), get(b, bios->status_flag));
        p += unparse_raw(p, q, path->length - 8);
        p += sprintf(p, ")");
        return p - buffer;