]> code.delx.au - refind/commitdiff
Added support for "-c" command-line parameter to rEFInd, to specify
authorsrs5694 <srs5694@users.sourceforge.net>
Mon, 30 Dec 2013 00:04:28 +0000 (19:04 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Mon, 30 Dec 2013 00:04:28 +0000 (19:04 -0500)
configuration file to use.

NEWS.txt
docs/refind/configfile.html
docs/refind/features.html
refind/config.c
refind/global.h
refind/lib.c
refind/lib.h
refind/main.c

index dd453193198d7de3189818b9f6cf0ecc2fcb474b..52c57d85dd6a417ee2956d5ca303dcfbd9087c94 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,15 @@
-0.7.7 (??/??/201?):
+0.7.7 (12/??/2013):
 -------------------
 
+- Added support for specifying the configuration file at program launch,
+  via the "-c" parameter, as in "refind_x64.efi -c foo.conf" to use the
+  foo.conf file as the main configuration file.
+
+- Scans of ext2/3/4fs and ReiserFS partitions now omit partitions with
+  duplicate filesystem UUIDs. These are likely parts of RAID arrays and so
+  would have the same boot loaders or kernels as the first one with a given
+  UUID.
+
 - Added feature in install.sh: Script now tries to locate and mount an ESP
   in Linux, if it's currently unmounted.
 
index 8516a571837ab9bb3cebf53b338cccd35bc52b2e..664c4d580a4bc16d25eebe8516787f45769fb569 100644 (file)
@@ -190,7 +190,9 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 <h2>Adjusting the Global Configuration</h2>
 </a>
 
-<p>You can adjust many of rEFInd's options by editing its <tt>refind.conf</tt> file. You can use any text editor you like for the job, but be sure it saves the file in plain ASCII text, not in a word processing format. (In theory, a UTF-16 encoding should also work, but I've not tried that myself.) Note that the EFI shell includes its own editor. If you need to make a change before you launch an OS, you can launch a shell, change to the rEFInd directory, and type <b><tt>edit refind.conf</tt></b> to edit the file. This EFI editor is quite primitive, but it gets the job done. After editing, you'll need to reboot for rEFInd to read the changed configuration file.</p>
+<p>You can adjust many of rEFInd's options by editing its configuration file. This file is called <tt>refind.conf</tt> by default; but you can use another filename by passing <tt>-c <tt class="variable">filename</tt></tt> as an option, as in <tt>refind_x64.efi -c myrefind.conf</tt> to use <tt>myrefind.conf</tt> in rEFInd's main directory. You can specify a configuration file in another directory, but to do so, you <i>must</i> use backslashes as directory separators, as in <tt>-c \EFI\other\refind.conf</tt>. This feature is intended for users who want to have rEFInd appear in its own menu, with the version launched in this way behaving differently from the original&mdash;for instance, to have a secondary rEFInd that provides boot options hidden by the main one. In this scenario, the default <tt>refind.conf</tt> would have a <a href="#stanzas">manual boot stanza</a> defining the new rEFInd instance, including its <tt>-c</tt> option.</p>
+
+<p>You can use any text editor you like to edit <tt>refind.conf</tt>, but be sure it saves the file in plain ASCII text, not in a word processing format. (In theory, a UTF-16 encoding should also work, but this has been poorly tested.) Note that the EFI shell includes its own editor. If you need to make a change before you launch an OS, you can launch a shell, change to the rEFInd directory, and type <b><tt>edit refind.conf</tt></b> to edit the file. This EFI editor is quite primitive, but it gets the job done. After editing, you'll need to reboot or re-launch rEFInd for rEFInd to read the changed configuration file.</p>
 
 <p>Global configuration file options consist of a name token followed by one or more parameters, as in:</p>
 
index 1c19a3dde92d1cf7c83edfc758c477b2bd9bc987..27f81cdec2686e557e6bef3857b91bfba91bf590 100644 (file)
@@ -161,6 +161,10 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <li>Bug fixes, focusing on those that have bothered me personally.</li>
 
+<li>The ability to specify a configuration file to use at program launch
+    time via the <tt>-c <tt class="variable">filename</tt></tt>
+    command-line option.</li>
+
 <li>User-configurable methods of detecting boot loaders:
 
     <ul>
index 26eeeff8a5a979f0c0bea825c21afb27d16b4f8b..a3e3900f504fa2342842923883f05f224c15e5e5 100644 (file)
@@ -411,7 +411,7 @@ VOID ReadConfig(CHAR16 *FileName)
     UINTN           TokenCount, i;
 
     // Set a few defaults only if we're loading the default file.
-    if (StriCmp(FileName, CONFIG_FILE_NAME) == 0) {
+    if (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0) {
        MyFreePool(GlobalConfig.AlsoScan);
        GlobalConfig.AlsoScan = StrDuplicate(ALSO_SCAN_DIRS);
        MyFreePool(GlobalConfig.DontScanDirs);
@@ -605,7 +605,8 @@ VOID ReadConfig(CHAR16 *FileName)
         } else if (StriCmp(TokenList[0], L"max_tags") == 0) {
            HandleInt(TokenList, TokenCount, &(GlobalConfig.MaxTags));
 
-        } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && (StriCmp(FileName, CONFIG_FILE_NAME) == 0)) {
+        } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) &&
+                   (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0)) {
            if (StriCmp(TokenList[1], FileName) != 0) {
               ReadConfig(TokenList[1]);
            }
@@ -844,7 +845,8 @@ VOID ScanUserConfigured(CHAR16 *FileName)
             } // if/else
             MyFreePool(Title);
 
-         } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) && (StriCmp(FileName, CONFIG_FILE_NAME) == 0)) {
+         } else if ((StriCmp(TokenList[0], L"include") == 0) && (TokenCount == 2) &&
+                    (StriCmp(FileName, GlobalConfig.ConfigFilename) == 0)) {
             if (StriCmp(TokenList[1], FileName) != 0) {
                ScanUserConfigured(TokenList[1]);
             }
index e6d4b4bc0ba4af893eb8d589ae3123233d60827a..8dc6d594ac8300167604aa7311d5ab40471ce6d6 100644 (file)
@@ -238,6 +238,7 @@ typedef struct {
    UINTN       ScreensaverTime;
    CHAR16      *BannerFileName;
    EG_IMAGE    *ScreenBackground;
+   CHAR16      *ConfigFilename;
    CHAR16      *SelectionSmallFileName;
    CHAR16      *SelectionBigFileName;
    CHAR16      *DefaultSelection;
index 49c0b996bea5cb33eb21fb06cf4128a4aa5845d8..c6a9257b1276b86fdb78f276af7adedde4f038aa 100644 (file)
@@ -471,7 +471,7 @@ static VOID SetFilesystemData(IN UINT8 *Buffer, IN UINTN BufferSize, IN OUT REFI
          }
       } // search for ext2/3/4 magic
 
-      if (BufferSize >= (65536 + 62)) {
+      if (BufferSize >= (65536 + 100)) {
          MagicString = (char*) (Buffer + 65536 + 52);
          if ((CompareMem(MagicString, REISERFS_SUPER_MAGIC_STRING, 8) == 0) ||
              (CompareMem(MagicString, REISER2FS_SUPER_MAGIC_STRING, 9) == 0) ||
@@ -1681,6 +1681,31 @@ CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index) {
    return (FoundString);
 } // CHAR16 *FindCommaDelimited()
 
+// Return the position of SmallString within BigString, or -1 if
+// not found.
+INTN FindSubString(IN CHAR16 *SmallString, IN CHAR16 *BigString) {
+   INTN Position = -1;
+   UINTN i = 0, SmallSize, BigSize;
+   BOOLEAN Found = FALSE;
+
+   if ((SmallString == NULL) || (BigString == NULL))
+      return -1;
+
+   SmallSize = StrLen(SmallString);
+   BigSize = StrLen(BigString);
+   if ((SmallSize > BigSize) || (SmallSize == 0) || (BigSize == 0))
+      return -1;
+
+   while ((i <= (BigSize - SmallSize) && !Found)) {
+      if (CompareMem(BigString + i, SmallString, SmallSize) == 0) {
+         Found = TRUE;
+         Position = i;
+      } // if
+      i++;
+   } // while()
+   return Position;
+} // INTN FindSubString()
+
 // Returns TRUE if SmallString is an element in the comma-delimited List,
 // FALSE otherwise. Performs comparison case-insensitively (except on
 // buggy EFIs with case-sensitive StriCmp() functions).
index d0a4022611a434b73f7ec5805fd6cec3995e6af8..bc3f87077c6438ed33c84719cbc299a025e45566 100644 (file)
@@ -114,6 +114,7 @@ VOID FindVolumeAndFilename(IN EFI_DEVICE_PATH *loadpath, OUT REFIT_VOLUME **Devi
 BOOLEAN SplitVolumeAndFilename(IN OUT CHAR16 **Path, OUT CHAR16 **VolName);
 CHAR16 *FindNumbers(IN CHAR16 *InString);
 CHAR16 *FindCommaDelimited(IN CHAR16 *InString, IN UINTN Index);
+INTN FindSubString(IN CHAR16 *SmallString, IN CHAR16 *BigString);
 BOOLEAN IsIn(IN CHAR16 *SmallString, IN CHAR16 *List);
 VOID MyFreePool(IN OUT VOID *Pointer);
 
index be3dca4a0b7a5789ef2ef97f17b40c325896e649..31fd8863d75cd74bb67779e1d401c410a7595086 100644 (file)
@@ -56,7 +56,9 @@
 #include "../include/syslinux_mbr.h"
 
 #ifdef __MAKEWITH_GNUEFI
+#ifndef EFI_SECURITY_VIOLATION
 #define EFI_SECURITY_VIOLATION    EFIERR (26)
+#endif
 #else
 #include "../EfiLib/BdsHelper.h"
 #include "../EfiLib/legacy.h"
@@ -130,7 +132,7 @@ static REFIT_MENU_SCREEN MainMenu       = { L"Main Menu", NULL, 0, NULL, 0, NULL
 static REFIT_MENU_SCREEN AboutMenu      = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL, L"Press Enter to return to main menu", L"" };
 
 REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0,
-                              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                              NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               { TAG_SHELL, TAG_MEMTEST, TAG_APPLE_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT, TAG_SHUTDOWN,
                                 TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 }
                             };
@@ -153,7 +155,7 @@ static VOID AboutrEFInd(VOID)
 {
     if (AboutMenu.EntryCount == 0) {
         AboutMenu.TitleImage = BuiltinIcon(BUILTIN_ICON_FUNC_ABOUT);
-        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.6.1");
+        AddMenuInfoLine(&AboutMenu, L"rEFInd Version 0.7.6.2");
         AddMenuInfoLine(&AboutMenu, L"");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2006-2010 Christoph Pfisterer");
         AddMenuInfoLine(&AboutMenu, L"Copyright (c) 2012-2013 Roderick W. Smith");
@@ -930,7 +932,7 @@ VOID SetLoaderDefaults(LOADER_ENTRY *Entry, CHAR16 *LoaderPath, REFIT_VOLUME *Vo
    } // if
 
    // detect specific loaders
-   if (StriSubCmp(L"bzImage", LoaderPath) || StriSubCmp(L"vmlinuz", LoaderPath)) {
+   if (StriSubCmp(L"bzImage", FileName) || StriSubCmp(L"vmlinuz", FileName)) {
       GuessLinuxDistribution(&OSIconName, Volume, LoaderPath);
       MergeStrings(&OSIconName, L"linux", L',');
       Entry->OSType = 'L';
@@ -2184,7 +2186,7 @@ static VOID ScanForBootloaders(VOID) {
             ScanLegacyExternal();
             break;
          case 'm': case 'M':
-            ScanUserConfigured(CONFIG_FILE_NAME);
+            ScanUserConfigured(GlobalConfig.ConfigFilename);
             break;
          case 'e': case 'E':
             ScanExternal();
@@ -2341,7 +2343,7 @@ VOID RescanAll(VOID) {
    FreeList((VOID ***) &(MainMenu.Entries), &MainMenu.EntryCount);
    MainMenu.Entries = NULL;
    MainMenu.EntryCount = 0;
-   ReadConfig(CONFIG_FILE_NAME);
+   ReadConfig(GlobalConfig.ConfigFilename);
    ConnectAllDriversToAllControllers();
    ScanVolumes();
    ScanForBootloaders();
@@ -2401,6 +2403,37 @@ static BOOLEAN SecureBootUninstall(VOID) {
    return Success;
 } // VOID SecureBootUninstall
 
+// Sets the global configuration filename; will be CONFIG_FILE_NAME unless the
+// "-c" command-line option is set, in which case that takes precedence.
+// If an error is encountered, leaves the value alone (it should be set to
+// CONFIG_FILE_NAME when GlobalConfig is initialized).
+static VOID SetConfigFilename(EFI_HANDLE ImageHandle) {
+   EFI_LOADED_IMAGE *Info;
+   CHAR16 *Options, *FileName;
+   EFI_STATUS Status;
+   INTN Where;
+
+   Status = uefi_call_wrapper(BS->HandleProtocol, 3, ImageHandle,
+                              &LoadedImageProtocol, (VOID **) &Info);
+   if ((Status == EFI_SUCCESS) && (Info->LoadOptionsSize > 0)) {
+      Options = (CHAR16 *) Info->LoadOptions;
+      Where = FindSubString(L" -c ", Options);
+      if (Where >= 0) {
+         FileName = StrDuplicate(&Options[Where + 4]);
+         Where = FindSubString(L" ", FileName);
+         if (Where > 0)
+            FileName[Where] = L'\0';
+
+         if (FileExists(SelfDir, FileName)) {
+            GlobalConfig.ConfigFilename = FileName;
+         } else {
+            Print(L"Specified configuration file (%s) doesn't exist; using\n'refind.conf' default\n", FileName);
+            MyFreePool(FileName);
+         } // if/else
+      } // if
+   } // if
+} // VOID SetConfigFilename()
+
 //
 // main entry point
 //
@@ -2427,7 +2460,8 @@ efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
     FindLegacyBootType();
     if (GlobalConfig.LegacyType == LEGACY_TYPE_MAC)
        CopyMem(GlobalConfig.ScanFor, "ihebocm   ", NUM_SCAN_OPTIONS);
-    ReadConfig(CONFIG_FILE_NAME);
+    SetConfigFilename(ImageHandle);
+    ReadConfig(GlobalConfig.ConfigFilename);
     ScanVolumes();
 
     InitScreen();