--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+
+
+my $EFIBOOTMGR = "/usr/sbin/efibootmgr -v";
+
+my %entries = get_efi_entries();
+
+my @net = efi_ipv4_pxe_entries(%entries);
+my @os = efi_os_entries(%entries);
+my @leftover;
+
+foreach my $i (keys %entries) {
+ my $found = 0;
+
+ foreach my $o (@net, @os) {
+ if ($i eq $o) {
+ print "FOUND $i $o\n";
+ $found = 1;
+ last;
+ }
+ }
+ if (! $found) {
+ push @leftover, $i;
+ }
+}
+
+my $order = join(",", @net, @os);
+
+my $cmd = "/usr/sbin/efibootmgr --bootorder=$order";
+exec($cmd);
+
+sub efi_os_entries {
+ my (%entries) = @_;
+
+ my %os;
+
+ foreach my $i (keys %entries) {
+ my $e = $entries{$i};
+
+ if ($$e{'type'} ne "os") {
+ next;
+ }
+
+ if ($os{$$e{'label'}}) {
+ $os{$$e{'label'} . "_" . $i} = $e;
+ }
+ else {
+ $os{$$e{'label'}} = $e;
+ }
+ }
+
+ my @order;
+ foreach my $i (sort keys %os) {
+
+ push @order, $os{$i}{'id'};
+ }
+ return @order;
+}
+
+
+sub efi_network_entries {
+ my (%entries) = @_;
+
+ my @order;
+ foreach my $i (keys %entries) {
+ my $e = $entries{$i};
+
+ if ($$e{'type'} ne "network") {
+ next;
+ }
+
+
+ #my $mac = $$e{'network'}{'mac'};
+ #my $type = $$e{'network'}{'type'};
+ #my $proto = $$e{'network'}{'protocol'};
+#
+ #if ($type eq "ipv4" && $proto eq "pxe") {
+ #$net{$mac} = $e;
+ #}
+ push @order, $$e{'id'};
+ }
+
+ @order = sort { $a cmp $b } @order;
+ return @order;
+}
+
+
+
+sub efi_ipv4_pxe_entries {
+ my (%entries) = @_;
+
+ my %net;
+
+ foreach my $i (keys %entries) {
+ my $e = $entries{$i};
+
+ if ($$e{'type'} ne "network") {
+ next;
+ }
+
+
+ my $mac = $$e{'network'}{'mac'};
+ my $type = $$e{'network'}{'type'};
+ my $proto = $$e{'network'}{'protocol'};
+
+ if ($type eq "ipv4" && $proto eq "pxe") {
+ $net{$mac} = $e;
+ }
+ }
+
+ my @order;
+ foreach my $i (sort keys %net) {
+
+ push @order, $net{$i}{'id'};
+ }
+ return @order;
+}
+
+sub get_efi_entries {
+ my @bootorder;
+ my %boot;
+
+ open (CMD, "$EFIBOOTMGR |") || die "Error opening $EFIBOOTMGR";
+ while (!eof(CMD)) {
+ my $line = <CMD>;
+ chomp $line;
+ if ($line =~ /^BootOrder/) {
+ $line =~ s/^BootOrder\:\s+//g;
+
+ @bootorder = split(/,/, $line);
+ }
+ elsif ($line =~ /^Boot[0-9]+/) {
+ $line =~ s/^Boot//g;
+ if ($line !~ /\*/) {
+ next;
+ }
+ $line =~ s/\*//g;
+ my @pieces = split(/\t/, $line);
+
+ my ($id, $label) = split(/ /, $pieces[0], 2);
+ my $device = $pieces[1];
+
+ my $entry_type = "";
+ my %entry = (
+ "id" => $id,
+ "label" => $label,
+ );
+
+ my %network;
+ # it's a network device...
+ if ($device =~ /MAC\(([0-9A-F]+),[0-9]+\)/i) {
+
+ my $mac = ${1};
+ my $net_type = "ipv6";
+
+ if ($device =~ /ipv4/i) {
+ $net_type = "ipv4";
+ }
+
+ my $protocol = "pxe";
+ if ($label =~ /http/i) {
+ $protocol = "http";
+ }
+
+ %network = (
+ "mac" => $mac,
+ "type" => $net_type,
+ "protocol" => $protocol
+ );
+
+ $entry_type = "network";
+ }
+ elsif ($device =~ /^Fv/) {
+ $entry_type = "firmware";
+ }
+ elsif ($device =~ /File/) {
+ $entry_type = "os";
+ }
+ else {
+ $entry_type = "unknown";
+ }
+
+ $entry{'network'} = \%network;
+ $entry{'type'} = $entry_type;
+ $boot{$id} = \%entry;
+ }
+ }
+ return %boot;
+}