]> code.delx.au - refind/blobdiff - refind/config.c
New ability to specify volume labels in "dont_scan_dirs" token to
[refind] / refind / config.c
index 3919127227a060bb9dbf714b59c5a48c586c9eeb..63d0f312857601b373667f3a9f41957d5c08a739 100644 (file)
@@ -53,7 +53,6 @@
 
 // constants
 
-#define CONFIG_FILE_NAME         L"refind.conf"
 #define LINUX_OPTIONS_FILENAMES  L"refind_linux.conf,refind-linux.conf"
 #define MAXCONFIGFILESIZE        (128*1024)
 
@@ -215,10 +214,43 @@ static CHAR16 *ReadLine(REFIT_FILE *File)
     return Line;
 }
 
+// Returns FALSE if *p points to the end of a token, TRUE otherwise.
+// Also modifies *p **IF** the first and second characters are both
+// quotes ('"'); it deletes one of them.
+static BOOLEAN KeepReading(IN OUT CHAR16 *p, IN OUT BOOLEAN *IsQuoted) {
+   BOOLEAN MoreToRead = FALSE;
+   CHAR16  *Temp = NULL;
+//            while (*p && *p != '"' && ((*p != ' ' && *p != '\t' && *p != '=' && *p != '#' && *p != ',') || IsQuoted)) {
+
+   if ((p == NULL) || (IsQuoted == NULL))
+      return FALSE;
+
+   if (*p == L'\0')
+      return FALSE;
+
+   if ((*p != ' ' && *p != '\t' && *p != '=' && *p != '#' && *p != ',') || *IsQuoted) {
+      MoreToRead = TRUE;
+   }
+   if (*p == L'"') {
+      if (p[1] == L'"') {
+         Temp = StrDuplicate(&p[1]);
+         if (Temp != NULL) {
+            StrCpy(p, Temp);
+            FreePool(Temp);
+         }
+         MoreToRead = TRUE;
+      } else {
+         *IsQuoted = !(*IsQuoted);
+         MoreToRead = FALSE;
+      } // if/else second character is a quote
+   } // if first character is a quote
+
+   return MoreToRead;
+} // BOOLEAN KeepReading()
+
 //
 // get a line of tokens from a file
 //
-
 UINTN ReadTokenLine(IN REFIT_FILE *File, OUT CHAR16 ***TokenList)
 {
     BOOLEAN         LineFinished, IsQuoted = FALSE;
@@ -235,7 +267,7 @@ UINTN ReadTokenLine(IN REFIT_FILE *File, OUT CHAR16 ***TokenList)
         p = Line;
         LineFinished = FALSE;
         while (!LineFinished) {
-            // skip whitespace
+            // skip whitespace & find start of token
             while ((*p == ' ' || *p == '\t' || *p == '=' || *p == ',') && !IsQuoted)
                 p++;
             if (*p == 0 || *p == '#')
@@ -248,14 +280,12 @@ UINTN ReadTokenLine(IN REFIT_FILE *File, OUT CHAR16 ***TokenList)
             Token = p;
 
             // find end of token
-            while (*p && *p != '"' && ((*p != ' ' && *p != '\t' && *p != '=' && *p != '#' && *p != ',') || IsQuoted)) {
-               if ((*p == '/') && !IsQuoted) // Switch Unix-style to DOS-style directory separators
-                  *p = '\\';
+            while (KeepReading(p, &IsQuoted)) {
+               if ((*p == L'/') && !IsQuoted) // Switch Unix-style to DOS-style directory separators
+                  *p = L'\\';
                p++;
-            } // if
-            if (*p == '"')
-               IsQuoted = !IsQuoted;
-            if (*p == 0 || *p == '#')
+            } // while
+            if (*p == L'\0' || *p == L'#')
                 LineFinished = TRUE;
             *p++ = 0;
 
@@ -305,25 +335,43 @@ static VOID HandleStrings(IN CHAR16 **TokenList, IN UINTN TokenCount, OUT CHAR16
 } // static VOID HandleStrings()
 
 // read config file
-VOID ReadConfig(VOID)
+VOID ReadConfig(CHAR16 *FileName)
 {
     EFI_STATUS      Status;
     REFIT_FILE      File;
     CHAR16          **TokenList;
     CHAR16          *FlagName;
+    CHAR16          *SelfPath = NULL;
     UINTN           TokenCount, i;
 
-    if (!FileExists(SelfDir, CONFIG_FILE_NAME)) {
-        Print(L"Configuration file missing!\n");
+    // Set a few defaults only if we're loading the default file.
+    if (StriCmp(FileName, CONFIG_FILE_NAME) == 0) {
+       MyFreePool(GlobalConfig.AlsoScan);
+       GlobalConfig.AlsoScan = StrDuplicate(ALSO_SCAN_DIRS);
+//        MyFreePool(GlobalConfig.DontScanVolumes);
+//        GlobalConfig.DontScanVolumes = StrDuplicate(L" ");
+       MyFreePool(GlobalConfig.DontScanDirs);
+       if (SelfVolume->VolName) {
+          SelfPath = StrDuplicate(SelfVolume->VolName);
+       } else {
+          SelfPath = AllocateZeroPool(256 * sizeof(CHAR16));
+          SPrint(SelfPath, 255, L"fs%d", SelfVolume->VolNumber);
+       } // if/else
+       MergeStrings(&SelfPath, SelfDirPath, L':');
+       GlobalConfig.DontScanDirs = SelfPath;
+       MyFreePool(GlobalConfig.DontScanFiles);
+       GlobalConfig.DontScanFiles = StrDuplicate(DONT_SCAN_FILES);
+    }
+
+    if (!FileExists(SelfDir, FileName)) {
+        Print(L"Configuration file '%s' missing!\n", FileName);
         return;
     }
 
-    Status = ReadFile(SelfDir, CONFIG_FILE_NAME, &File, &i);
+    Status = ReadFile(SelfDir, FileName, &File, &i);
     if (EFI_ERROR(Status))
         return;
 
-    GlobalConfig.DontScan = StrDuplicate(SelfDirPath);
-
     for (;;) {
         TokenCount = ReadTokenLine(&File, &TokenList);
         if (TokenCount == 0)
@@ -340,13 +388,17 @@ VOID ReadConfig(VOID)
                 } else if (StriCmp(FlagName, L"label") == 0) {
                    GlobalConfig.HideUIFlags |= HIDEUI_FLAG_LABEL;
                 } else if (StriCmp(FlagName, L"singleuser") == 0) {
-                    GlobalConfig.HideUIFlags |= HIDEUI_FLAG_SINGLEUSER;
+                   GlobalConfig.HideUIFlags |= HIDEUI_FLAG_SINGLEUSER;
                 } else if (StriCmp(FlagName, L"hwtest") == 0) {
-                    GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HWTEST;
+                   GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HWTEST;
                 } else if (StriCmp(FlagName, L"arrows") == 0) {
                    GlobalConfig.HideUIFlags |= HIDEUI_FLAG_ARROWS;
+                } else if (StriCmp(FlagName, L"hints") == 0) {
+                   GlobalConfig.HideUIFlags |= HIDEUI_FLAG_HINTS;
+                } else if (StriCmp(FlagName, L"editor") == 0) {
+                   GlobalConfig.HideUIFlags |= HIDEUI_FLAG_EDITOR;
                 } else if (StriCmp(FlagName, L"all") == 0) {
-                    GlobalConfig.HideUIFlags = HIDEUI_ALL;
+                   GlobalConfig.HideUIFlags = HIDEUI_FLAG_ALL;
                 } else {
                     Print(L" unknown hideui flag: '%s'\n", FlagName);
                 }
@@ -369,8 +421,20 @@ VOID ReadConfig(VOID)
         } else if (StriCmp(TokenList[0], L"also_scan_dirs") == 0) {
             HandleStrings(TokenList, TokenCount, &(GlobalConfig.AlsoScan));
 
+        } else if ((StriCmp(TokenList[0], L"don't_scan_volumes") == 0) || (StriCmp(TokenList[0], L"dont_scan_volumes") == 0)) {
+           HandleStrings(TokenList, TokenCount, &(GlobalConfig.AlsoScan));
+           // Note: Don't use HandleStrings() because it modifies slashes, which might be present in volume name
+            MyFreePool(GlobalConfig.DontScanVolumes);
+            GlobalConfig.DontScanVolumes = NULL;
+            for (i = 1; i < TokenCount; i++) {
+               MergeStrings(&GlobalConfig.DontScanVolumes, TokenList[i], L',');
+            }
+
         } else if ((StriCmp(TokenList[0], L"don't_scan_dirs") == 0) || (StriCmp(TokenList[0], L"dont_scan_dirs") == 0)) {
-            HandleStrings(TokenList, TokenCount, &(GlobalConfig.DontScan));
+            HandleStrings(TokenList, TokenCount, &(GlobalConfig.DontScanDirs));
+
+        } else if ((StriCmp(TokenList[0], L"don't_scan_files") == 0) || (StriCmp(TokenList[0], L"dont_scan_files") == 0)) {
+           HandleStrings(TokenList, TokenCount, &(GlobalConfig.DontScanFiles));
 
         } else if (StriCmp(TokenList[0], L"scan_driver_dirs") == 0) {
             HandleStrings(TokenList, TokenCount, &(GlobalConfig.DriverDirs));
@@ -413,11 +477,21 @@ VOID ReadConfig(VOID)
            HandleString(TokenList, TokenCount, &(GlobalConfig.DefaultSelection));
 
         } else if (StriCmp(TokenList[0], L"textonly") == 0) {
-            GlobalConfig.TextOnly = TRUE;
+           if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) {
+              GlobalConfig.TextOnly = FALSE;
+           } else {
+              GlobalConfig.TextOnly = TRUE;
+           }
+
+        } else if (StriCmp(TokenList[0], L"textmode") == 0) {
+           HandleInt(TokenList, TokenCount, &(GlobalConfig.RequestedTextMode));
 
-        } else if ((StriCmp(TokenList[0], L"resolution") == 0) && (TokenCount == 3)) {
+        } else if ((StriCmp(TokenList[0], L"resolution") == 0) && ((TokenCount == 2) || (TokenCount == 3))) {
            GlobalConfig.RequestedScreenWidth = Atoi(TokenList[1]);
-           GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
+           if (TokenCount == 3)
+              GlobalConfig.RequestedScreenHeight = Atoi(TokenList[2]);
+           else
+              GlobalConfig.RequestedScreenHeight = 0;
 
         } else if (StriCmp(TokenList[0], L"use_graphics_for") == 0) {
            GlobalConfig.GraphicsFor = 0;
@@ -436,11 +510,20 @@ VOID ReadConfig(VOID)
            } // for (graphics_on tokens)
 
         } else if (StriCmp(TokenList[0], L"scan_all_linux_kernels") == 0) {
-           GlobalConfig.ScanAllLinux = TRUE;
+           if ((TokenCount >= 2) && (StriCmp(TokenList[1], L"0") == 0)) {
+              GlobalConfig.ScanAllLinux = FALSE;
+           } else {
+              GlobalConfig.ScanAllLinux = TRUE;
+           }
 
         } 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)) {
+           if (StriCmp(TokenList[1], FileName) != 0) {
+              ReadConfig(TokenList[1]);
+           }
+
         }
 
         FreeTokenLine(&TokenList, &TokenCount);
@@ -643,7 +726,7 @@ static LOADER_ENTRY * AddStanzaEntries(REFIT_FILE *File, REFIT_VOLUME *Volume, C
    return(Entry);
 } // static VOID AddStanzaEntries()
 
-// Read the user-configured loaders file, refind_loaders.conf, and add or delete
+// Read the user-configured menu entries from refind.conf and add or delete
 // entries based on the contents of that file....
 VOID ScanUserConfigured(VOID)
 {