]> code.delx.au - refind/commitdiff
Time support in default_selection; enables different default based on
authorsrs5694 <srs5694@users.sourceforge.net>
Sun, 15 Dec 2013 05:10:46 +0000 (00:10 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Sun, 15 Dec 2013 05:10:46 +0000 (00:10 -0500)
time of day.

BUILDING.txt
NEWS.txt
docs/refind/configfile.html
refind/config.c
refind/config.h
refind/main.c

index 917a66a1e171cdaccbf8d547cf7b26d1f27090c8..b35ed4e9cf81fcadd480ebd6f862975b1ac276a7 100644 (file)
@@ -28,19 +28,20 @@ To compile rEFInd, you'll need the following:
     install this from a package called "gnu-efi"; however, rEFInd relies on
     features that were added in (I think) 3.0l to provide driver-loading
     capabilities. The versions I've used and that work are 3.0p, 3.0q,
     install this from a package called "gnu-efi"; however, rEFInd relies on
     features that were added in (I think) 3.0l to provide driver-loading
     capabilities. The versions I've used and that work are 3.0p, 3.0q,
-    3.0r, and 3.0s, with the caveat that 3.0s works when I installed it via
-    a Gentoo package, but not when I installed it by compiling the source
-    code locally. Through mid-to-late 2012, most Linux distributions
-    delivered rather elderly versions of GNU-EFI, but many are catching up
-    by late 2012. You should check your GNU-EFI version number; you may
-    need to download the latest source code, compile it, and install it
-    locally. Between rEFInd version 0.2.7 and 0.6.1, the Makefiles assumed
-    a locally-compiled GNU-EFI package, but older and more recent versions
-    assume GNU-EFI installation in typical locations for
-    distribution-provided packages. The legacy BIOS boot support on
-    UEFI-based PCs doesn't work when rEFInd is compiled under GNU-EFI, so
-    as of rEFInd 0.4.6, GNU-EFI is no longer the primary build environment,
-    although it's easier to set up on a Linux system.
+    3.0r, 3.0s, and 3.0u, with a caveat: The new time-sensitive
+    default_selection feature causes rEFInd to hang when using 3.0s and
+    earlier. 3.0u works fine for this (tested with compilation on three
+    computers). I don't know if 3.0t would work. Through mid-to-late 2012,
+    most Linux distributions delivered rather elderly versions of GNU-EFI,
+    but many are catching up by late 2012. You should check your GNU-EFI
+    version number; you may need to download the latest source code,
+    compile it, and install it locally. Between rEFInd version 0.2.7 and
+    0.6.1, the Makefiles assumed a locally-compiled GNU-EFI package, but
+    older and more recent versions assume GNU-EFI installation in typical
+    locations for distribution-provided packages. The legacy BIOS boot
+    support on UEFI-based PCs doesn't work when rEFInd is compiled under
+    GNU-EFI, so as of rEFInd 0.4.6, GNU-EFI is no longer the primary build
+    environment, although it's easier to set up on a Linux system.
 
 Of the two toolkits, I prefer to use TianoCore because it produces binaries
 that can boot BIOS/legacy-mode OSes and because the TianoCore-produced
 
 Of the two toolkits, I prefer to use TianoCore because it produces binaries
 that can boot BIOS/legacy-mode OSes and because the TianoCore-produced
index bcfefd45d3fb2ecee7480eb5d5b3a29340d05fa6..163936cd85afaee7e4dcb8c5847adfe1931f40b3 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,18 @@
 0.7.6 (12/??/2013):
 -------------------
 
 0.7.6 (12/??/2013):
 -------------------
 
+- Added support for time-sensitive "default_selection" setting. This token
+  may now have either one or three options. If one, it's interpreted as it
+  has been in the past, as setting a default that's independent of times.
+  If you follow this default by two times, however, those are interpreted
+  as the start and end times (in 24-hour format) for a default setting. For
+  instance, "default_selection foo 8:00 17:00" causes foo to be the default
+  from 8:00 (AM) to 17:00 (aka 5:00 PM). You can include multiple
+  "default_selection" lines to set different defaults for a variety of
+  times. If they're in conflict, the last one takes precedence. Note that
+  times are hardware clock's native value, which may be local time or UTC,
+  depending on your computer.
+
 - Added support for a blank-screen startup: Set "screensaver -1" and the
   screen saver will be initialized when rEFInd starts. If you set a low
   "timeout" value, the result will be a boot straight to the default OS
 - Added support for a blank-screen startup: Set "screensaver -1" and the
   screen saver will be initialized when rEFInd starts. If you set a low
   "timeout" value, the result will be a boot straight to the default OS
index 4bae3e57c8bb72fb3b4dbd6e1cfd04299d10ed21..9f78ba9c0a87f405fee9b85f14989791770fb6d6 100644 (file)
@@ -318,8 +318,8 @@ timeout 20
 </tr>
 <tr>
    <td><tt>default_selection</tt></td>
 </tr>
 <tr>
    <td><tt>default_selection</tt></td>
-   <td>a substring of a boot loader's title; or a numeric position</td>
-   <td>Sets the default boot OS based on the loader's title, which appears in the main menu beneath the icons when you select the loader. You can enter any substring of the title as the <tt>default_selection</tt>, so long as it's two or more characters in length. It's best to use a unique substring, since rEFInd stops searching when it finds the first match. Because rEFInd sorts entries within a directory in descending order by file modification time, if you specify a directory (or volume name, for loaders in a partition's root directory) as the <tt>default_selection</tt>, the most recent loader in that directory will be the default. One-character entries are matched against the first character of the title, except for digits, which refer to the numeric order of the boot loader entries.</td>
+   <td>a substring of a boot loader's title, or a numeric position; optionally followed by two times in <tt class="variable">HH:MM</tt> format</td>
+   <td>Sets the default boot OS based on the loader's title, which appears in the main menu beneath the icons when you select the loader. You can enter any substring of the title as the <tt>default_selection</tt>, so long as it's two or more characters in length. It's best to use a unique substring, since rEFInd stops searching when it finds the first match. Because rEFInd sorts entries within a directory in descending order by file modification time, if you specify a directory (or volume name, for loaders in a partition's root directory) as the <tt>default_selection</tt>, the most recent loader in that directory will be the default. One-character entries are matched against the first character of the title, except for digits, which refer to the numeric order of the boot loader entries. You may optionally follow the match string by two times, in 24-hour format, in which case the entry applies only between those two times. For instance, <tt>default_selection Safety 1:30 2:30</tt> boots the entry called <tt>Safety</tt> by default between the hours of 1:30 and 2:30. These times are specified in whatever format the motherboard clock uses (local time or UTC). If the first value is larger than the second, as in <tt>23:00 1:00</tt>, it is interpreted as crossing midnight&mdash;11:00 PM to 1:00 AM in this example. The last <tt>default_selection</tt> setting takes precedence over preceding ones <i>if</i> the time value matches. Thus, you can set a main <tt>default_selection</tt> without a time specification and then set one or more others to override the main setting at specific times.</td>
 </tr>
 <tr>
    <td><tt>include</tt></td>
 </tr>
 <tr>
    <td><tt>include</tt></td>
index c310e30043f4a93a31de2dba64b256262598d1e6..f86edc836fb8fc597446e45c1459eba2312db1e8 100644 (file)
@@ -60,6 +60,9 @@
 #define ENCODING_UTF8       (1)
 #define ENCODING_UTF16_LE   (2)
 
 #define ENCODING_UTF8       (1)
 #define ENCODING_UTF16_LE   (2)
 
+#define GetTime ST->RuntimeServices->GetTime
+#define LAST_MINUTE 1439 /* Last minute of a day */
+
 static REFIT_MENU_ENTRY MenuEntryReturn   = { L"Return to Main Menu", TAG_RETURN, 0, 0, 0, NULL, NULL, NULL };
 
 //
 static REFIT_MENU_ENTRY MenuEntryReturn   = { L"Return to Main Menu", TAG_RETURN, 0, 0, 0, NULL, NULL, NULL };
 
 //
@@ -337,6 +340,85 @@ static VOID HandleStrings(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16
    }
 } // static VOID HandleStrings()
 
    }
 } // static VOID HandleStrings()
 
+// Convert TimeString (in "HH:MM" format) to a pure-minute format. Values should be
+// in the range from 0 (for 00:00, or midnight) to 1439 (for 23:59; aka LAST_MINUTE).
+// Any value outside that range denotes an error in the specification.
+// static UINTN HandleTime(IN CHAR16 *TimeString) {
+//    BOOLEAN Found = FALSE;
+//    UINTN ColonPosition = 0, Hour = 0, Minute = 0, TimeLength;
+// 
+//    Print(L"Entering HandleTime('%s')\n", TimeString);
+//    TimeLength = StrLen(TimeString);
+//    for (ColonPosition = 0; (ColonPosition < TimeLength) && !Found; ColonPosition++) {
+//       Print(L"ColonPosition = %d\n", ColonPosition);
+//       if (TimeString[ColonPosition] == ':')
+//          Found = TRUE;
+//    } // for
+// 
+//    if ((ColonPosition == 0) || (ColonPosition > StrLen(TimeString)))
+//       return (LAST_MINUTE + 1);
+// 
+//    Hour = Atoi(TimeString);
+//    Minute = Atoi(&TimeString[ColonPosition + 1]);
+//    Print(L"Hour = %d, Minute = %d\n", Hour, Minute);
+//    return (Hour * 60 + Minute);
+// } // BOOLEAN HandleTime()
+
+static UINTN HandleTime(IN CHAR16 *TimeString) {
+   UINTN Hour = 0, Minute = 0, TimeLength, i = 0;
+   BOOLEAN FoundColon = FALSE;
+
+   TimeLength = StrLen(TimeString);
+   while (i < TimeLength) {
+      if (TimeString[i] == L':') {
+         FoundColon = TRUE;
+         Hour = Minute;
+         Minute = 0;
+      } // if
+      if ((TimeString[i] >= L'0') && (TimeString[i] <= '9')) {
+         Minute *= 10;
+         Minute += (TimeString[i] - L'0');
+      } // if
+      i++;
+   } // while
+   return (FoundColon ? Hour * 60 + Minute : LAST_MINUTE + 1);
+} // BOOLEAN HandleTime()
+
+// Sets the default boot loader IF the current time is within the bounds
+// defined by the third and fourth tokens in the TokenList.
+static VOID SetDefaultByTime(IN CHAR16 **TokenList, OUT CHAR16 **Default) {
+   EFI_STATUS            Status;
+   EFI_TIME              CurrentTime;
+   UINTN                 StartTime = LAST_MINUTE + 1, EndTime = LAST_MINUTE + 1, Now;
+   BOOLEAN               SetIt = FALSE;
+
+   StartTime = HandleTime(TokenList[2]);
+   EndTime = HandleTime(TokenList[3]);
+
+   if ((StartTime <= LAST_MINUTE) && (EndTime <= LAST_MINUTE)) {
+      Status = refit_call2_wrapper(GetTime, &CurrentTime, NULL);
+      Now = CurrentTime.Hour * 60 + CurrentTime.Minute;
+
+      if (Now > LAST_MINUTE) { // Shouldn't happen; just being paranoid
+         Print(L"Warning: Impossible system time: %d:%d\n", CurrentTime.Hour, CurrentTime.Minute);
+         return;
+      } // if impossible time
+
+      if (StartTime < EndTime) { // Time range does NOT cross midnight
+         if ((Now >= StartTime) && (Now <= EndTime))
+            SetIt = TRUE;
+      } else { // Time range DOES cross midnight
+         if ((Now >= StartTime) && (Now <= EndTime))
+            SetIt = TRUE;
+      } // if/else time range crosses midnight
+
+      if (SetIt) {
+         MyFreePool(*Default);
+         *Default = StrDuplicate(TokenList[1]);
+      } // if (SetIt)
+   } // if ((StartTime <= LAST_MINUTE) && (EndTime <= LAST_MINUTE))
+} // VOID SetDefaultByTime()
+
 // read config file
 VOID ReadConfig(CHAR16 *FileName)
 {
 // read config file
 VOID ReadConfig(CHAR16 *FileName)
 {
@@ -487,7 +569,11 @@ VOID ReadConfig(CHAR16 *FileName)
            HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionBigFileName));
 
         } else if (StriCmp(TokenList[0], L"default_selection") == 0) {
            HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionBigFileName));
 
         } else if (StriCmp(TokenList[0], L"default_selection") == 0) {
-           HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection));
+           if (TokenCount == 4) {
+              SetDefaultByTime(TokenList, &(GlobalConfig.DefaultSelection));
+           } else {
+              HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection));
+           }
 
         } else if (StriCmp(TokenList[0], L"textonly") == 0) {
            if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) {
 
         } else if (StriCmp(TokenList[0], L"textonly") == 0) {
            if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) {
index aad46a69b54f3f4e61bd7fd4ae44ffbcd552b696..3c92fdb4c36bcc08e84318e8e1125909e73ade7a 100644 (file)
@@ -53,6 +53,7 @@
 #endif
 #include "global.h"
 
 #endif
 #include "global.h"
 
+
 //
 // config module
 //
 //
 // config module
 //
index 14296b9fc520b27fad032853ff77cb10e5adfa96..83c44e730e8ade5afbc740b8e63fa2176cd2f1ac 100644 (file)
@@ -153,7 +153,7 @@ static VOID AboutrEFInd(VOID)
 {
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
 {
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.5");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.5.2");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith");