Magellan Linux

Diff of /trunk/grubby/grubby.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2257 by niro, Mon Oct 21 14:01:48 2013 UTC revision 2986 by niro, Thu Jun 30 10:30:31 2016 UTC
# Line 60  int debug = 0; /* Currently just for tem Line 60  int debug = 0; /* Currently just for tem
60    
61  int isEfi = 0;  int isEfi = 0;
62    
63    #if defined(__aarch64__)
64    #define isEfiOnly 1
65    #else
66    #define isEfiOnly 0
67    #endif
68    
69  char *saved_command_line = NULL;  char *saved_command_line = NULL;
70    
71  /* comments get lumped in with indention */  /* comments get lumped in with indention */
# Line 90  enum lineType_e { Line 96  enum lineType_e {
96      LT_SET_VARIABLE = 1 << 19,      LT_SET_VARIABLE = 1 << 19,
97      LT_KERNEL_EFI   = 1 << 20,      LT_KERNEL_EFI   = 1 << 20,
98      LT_INITRD_EFI   = 1 << 21,      LT_INITRD_EFI   = 1 << 21,
99      LT_UNKNOWN      = 1 << 22,      LT_KERNEL_16    = 1 << 22,
100        LT_INITRD_16    = 1 << 23,
101        LT_DEVTREE      = 1 << 24,
102        LT_UNKNOWN      = 1 << 25,
103  };  };
104    
105  struct singleLine {  struct singleLine {
# Line 119  struct singleEntry { Line 128  struct singleEntry {
128  #define NEED_ARGS    (1 << 3)  #define NEED_ARGS    (1 << 3)
129  #define NEED_MB      (1 << 4)  #define NEED_MB      (1 << 4)
130  #define NEED_END     (1 << 5)  #define NEED_END     (1 << 5)
131    #define NEED_DEVTREE (1 << 6)
132    
133  #define MAIN_DEFAULT    (1 << 0)  #define MAIN_DEFAULT    (1 << 0)
134  #define DEFAULT_SAVED       -2  #define DEFAULT_SAVED       -2
# Line 151  struct configFileInfo { Line 161  struct configFileInfo {
161      int defaultIsVariable;      int defaultIsVariable;
162      int defaultSupportSaved;      int defaultSupportSaved;
163      int defaultIsSaved;      int defaultIsSaved;
164        int defaultIsUnquoted;
165      enum lineType_e entryStart;      enum lineType_e entryStart;
166      enum lineType_e entryEnd;      enum lineType_e entryEnd;
167      int needsBootPrefix;      int needsBootPrefix;
# Line 182  const char *grubFindConfig(struct config Line 193  const char *grubFindConfig(struct config
193   "/boot/grub/grub.conf",   "/boot/grub/grub.conf",
194   "/boot/grub/menu.lst",   "/boot/grub/menu.lst",
195   "/etc/grub.conf",   "/etc/grub.conf",
196     "/boot/grub2/grub.cfg",
197     "/boot/grub2-efi/grub.cfg",
198   NULL   NULL
199      };      };
200      static int i = -1;      static int i = -1;
# Line 209  struct configFileInfo grubConfigType = { Line 222  struct configFileInfo grubConfigType = {
222      .mbHyperFirst = 1,      .mbHyperFirst = 1,
223      .mbInitRdIsModule = 1,      .mbInitRdIsModule = 1,
224      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
225        .titlePosition = 1,
226  };  };
227    
228  struct keywordTypes grub2Keywords[] = {  struct keywordTypes grub2Keywords[] = {
# Line 221  struct keywordTypes grub2Keywords[] = { Line 235  struct keywordTypes grub2Keywords[] = {
235      { "fallback",   LT_FALLBACK,    ' ' },      { "fallback",   LT_FALLBACK,    ' ' },
236      { "linux",      LT_KERNEL,      ' ' },      { "linux",      LT_KERNEL,      ' ' },
237      { "linuxefi",   LT_KERNEL_EFI,  ' ' },      { "linuxefi",   LT_KERNEL_EFI,  ' ' },
238        { "linux16",    LT_KERNEL_16,   ' ' },
239      { "initrd",     LT_INITRD,      ' ', ' ' },      { "initrd",     LT_INITRD,      ' ', ' ' },
240      { "initrdefi",  LT_INITRD_EFI,  ' ', ' ' },      { "initrdefi",  LT_INITRD_EFI,  ' ', ' ' },
241        { "initrd16",   LT_INITRD_16,   ' ', ' ' },
242      { "module",     LT_MBMODULE,    ' ' },      { "module",     LT_MBMODULE,    ' ' },
243      { "kernel",     LT_HYPER,       ' ' },      { "kernel",     LT_HYPER,       ' ' },
244        { "devicetree", LT_DEVTREE,  ' ' },
245      { NULL, 0, 0 },      { NULL, 0, 0 },
246  };  };
247    
# Line 273  static char *grub2GetEnv(struct configFi Line 290  static char *grub2GetEnv(struct configFi
290      static char buf[1025];      static char buf[1025];
291      char *s = NULL;      char *s = NULL;
292      char *ret = NULL;      char *ret = NULL;
293      char *envFile = info->envFile ? info->envFile : "/boot/grub2/grubenv";      char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv";
294      int rc = asprintf(&s, "grub2-editenv %s list | grep '^%s='", envFile, name);      int rc = asprintf(&s, "grub-editenv %s list | grep '^%s='", envFile, name);
295    
296      if (rc < 0)      if (rc < 0)
297   return NULL;   return NULL;
# Line 338  static int grub2SetEnv(struct configFile Line 355  static int grub2SetEnv(struct configFile
355  {  {
356      char *s = NULL;      char *s = NULL;
357      int rc = 0;      int rc = 0;
358      char *envFile = info->envFile ? info->envFile : "/boot/grub2/grubenv";      char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv";
359    
360      unquote(value);      unquote(value);
361      value = shellEscape(value);      value = shellEscape(value);
362      if (!value)      if (!value)
363      return -1;      return -1;
364    
365      rc = asprintf(&s, "grub2-editenv %s set '%s=%s'", envFile, name, value);      rc = asprintf(&s, "grub-editenv %s set '%s=%s'", envFile, name, value);
366      free(value);      free(value);
367      if (rc <0)      if (rc <0)
368   return -1;   return -1;
# Line 396  static int isquote(char q) Line 413  static int isquote(char q)
413  }  }
414    
415  static int iskernel(enum lineType_e type) {  static int iskernel(enum lineType_e type) {
416      return (type == LT_KERNEL || type == LT_KERNEL_EFI);      return (type == LT_KERNEL || type == LT_KERNEL_EFI || type == LT_KERNEL_16);
417  }  }
418    
419  static int isinitrd(enum lineType_e type) {  static int isinitrd(enum lineType_e type) {
420      return (type == LT_INITRD || type == LT_INITRD_EFI);      return (type == LT_INITRD || type == LT_INITRD_EFI || type == LT_INITRD_16);
421  }  }
422    
423  char *grub2ExtractTitle(struct singleLine * line) {  char *grub2ExtractTitle(struct singleLine * line) {
# Line 566  struct keywordTypes extlinuxKeywords[] = Line 583  struct keywordTypes extlinuxKeywords[] =
583      { "initrd",    LT_INITRD,      ' ', ',' },      { "initrd",    LT_INITRD,      ' ', ',' },
584      { "append",    LT_KERNELARGS,  ' ' },      { "append",    LT_KERNELARGS,  ' ' },
585      { "prompt",     LT_UNKNOWN,     ' ' },      { "prompt",     LT_UNKNOWN,     ' ' },
586        { "fdt",        LT_DEVTREE,     ' ' },
587        { "fdtdir",     LT_DEVTREE,     ' ' },
588      { NULL,    0, 0 },      { NULL,    0, 0 },
589  };  };
590  int useextlinuxmenu;  int useextlinuxmenu;
# Line 576  struct configFileInfo eliloConfigType = Line 595  struct configFileInfo eliloConfigType =
595      .needsBootPrefix = 1,      .needsBootPrefix = 1,
596      .argsInQuotes = 1,      .argsInQuotes = 1,
597      .mbConcatArgs = 1,      .mbConcatArgs = 1,
598        .titlePosition = 1,
599  };  };
600    
601  struct configFileInfo liloConfigType = {  struct configFileInfo liloConfigType = {
# Line 584  struct configFileInfo liloConfigType = { Line 604  struct configFileInfo liloConfigType = {
604      .entryStart = LT_KERNEL,      .entryStart = LT_KERNEL,
605      .argsInQuotes = 1,      .argsInQuotes = 1,
606      .maxTitleLength = 15,      .maxTitleLength = 15,
607        .titlePosition = 1,
608  };  };
609    
610  struct configFileInfo yabootConfigType = {  struct configFileInfo yabootConfigType = {
# Line 594  struct configFileInfo yabootConfigType = Line 615  struct configFileInfo yabootConfigType =
615      .argsInQuotes = 1,      .argsInQuotes = 1,
616      .maxTitleLength = 15,      .maxTitleLength = 15,
617      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
618        .titlePosition = 1,
619  };  };
620    
621  struct configFileInfo siloConfigType = {  struct configFileInfo siloConfigType = {
# Line 603  struct configFileInfo siloConfigType = { Line 625  struct configFileInfo siloConfigType = {
625      .needsBootPrefix = 1,      .needsBootPrefix = 1,
626      .argsInQuotes = 1,      .argsInQuotes = 1,
627      .maxTitleLength = 15,      .maxTitleLength = 15,
628        .titlePosition = 1,
629  };  };
630    
631  struct configFileInfo ziplConfigType = {  struct configFileInfo ziplConfigType = {
# Line 621  struct configFileInfo extlinuxConfigType Line 644  struct configFileInfo extlinuxConfigType
644      .needsBootPrefix = 1,      .needsBootPrefix = 1,
645      .maxTitleLength = 255,      .maxTitleLength = 255,
646      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
647        .defaultIsUnquoted = 1,
648        .titlePosition = 1,
649  };  };
650    
651  struct grubConfig {  struct grubConfig {
# Line 712  static enum lineType_e preferredLineType Line 737  static enum lineType_e preferredLineType
737      if (isEfi && cfi == &grub2ConfigType) {      if (isEfi && cfi == &grub2ConfigType) {
738   switch (type) {   switch (type) {
739   case LT_KERNEL:   case LT_KERNEL:
740      return LT_KERNEL_EFI;      return isEfiOnly ? LT_KERNEL : LT_KERNEL_EFI;
741     case LT_INITRD:
742        return isEfiOnly ? LT_INITRD : LT_INITRD_EFI;
743     default:
744        return type;
745     }
746    #if defined(__i386__) || defined(__x86_64__)
747        } else if (cfi == &grub2ConfigType) {
748     switch (type) {
749     case LT_KERNEL:
750        return LT_KERNEL_16;
751   case LT_INITRD:   case LT_INITRD:
752      return LT_INITRD_EFI;      return LT_INITRD_16;
753   default:   default:
754      return type;      return type;
755   }   }
756    #endif
757      }      }
758      return type;      return type;
759  }  }
# Line 798  static int isEntryStart(struct singleLin Line 834  static int isEntryStart(struct singleLin
834  }  }
835    
836  /* extract the title from within brackets (for zipl) */  /* extract the title from within brackets (for zipl) */
837  static char * extractTitle(struct singleLine * line) {  static char * extractTitle(struct grubConfig *cfg, struct singleLine * line) {
838      /* bracketed title... let's extract it (leaks a byte) */      /* bracketed title... let's extract it */
839      char * title = NULL;      char * title = NULL;
840      if (line->type == LT_TITLE) {      if (line->type == LT_TITLE) {
841   title = strdup(line->elements[0].item);   char *tmp = line->elements[cfg->cfi->titlePosition].item;
842   title++;   if (cfg->cfi->titleBracketed) {
843   *(title + strlen(title) - 1) = '\0';      tmp++;
844        title = strdup(tmp);
845        *(title + strlen(title) - 1) = '\0';
846     } else {
847        title = strdup(tmp);
848     }
849      } else if (line->type == LT_MENUENTRY)      } else if (line->type == LT_MENUENTRY)
850   title = strdup(line->elements[1].item);   title = strdup(line->elements[1].item);
851      else      else
# Line 1066  static int getNextLine(char ** bufPtr, s Line 1107  static int getNextLine(char ** bufPtr, s
1107      return 0;      return 0;
1108  }  }
1109    
1110    static int isnumber(const char *s)
1111    {
1112        int i;
1113        for (i = 0; s[i] != '\0'; i++)
1114     if (s[i] < '0' || s[i] > '9')
1115        return 0;
1116        return i;
1117    }
1118    
1119  static struct grubConfig * readConfig(const char * inName,  static struct grubConfig * readConfig(const char * inName,
1120        struct configFileInfo * cfi) {        struct configFileInfo * cfi) {
1121      int in;      int in;
# Line 1156  static struct grubConfig * readConfig(co Line 1206  static struct grubConfig * readConfig(co
1206   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1207   defaultLine = line;   defaultLine = line;
1208      }      }
  } else if (line->type == LT_DEFAULT && line->numElements == 2) {  
     cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;  
     defaultLine = line;  
1209    
1210          } else if (iskernel(line->type)) {          } else if (iskernel(line->type)) {
1211      /* if by some freak chance this is multiboot and the "module"      /* if by some freak chance this is multiboot and the "module"
1212       * lines came earlier in the template, make sure to use LT_HYPER       * lines came earlier in the template, make sure to use LT_HYPER
1213       * instead of LT_KERNEL now       * instead of LT_KERNEL now
1214       */       */
1215      if (entry->multiboot)      if (entry && entry->multiboot)
1216   line->type = LT_HYPER;   line->type = LT_HYPER;
1217    
1218          } else if (line->type == LT_MBMODULE) {          } else if (line->type == LT_MBMODULE) {
# Line 1191  static struct grubConfig * readConfig(co Line 1238  static struct grubConfig * readConfig(co
1238      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);
1239      if (*end) cfg->fallbackImage = -1;      if (*end) cfg->fallbackImage = -1;
1240    
1241   } else if (line->type == LT_TITLE && line->numElements > 1) {   } else if ((line->type == LT_DEFAULT && cfi->defaultIsUnquoted) ||
1242      /* make the title a single argument (undoing our parsing) */                  (line->type == LT_TITLE && line->numElements > 1)) {
1243        /* make the title/default a single argument (undoing our parsing) */
1244      len = 0;      len = 0;
1245      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1246   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1299  static struct grubConfig * readConfig(co Line 1347  static struct grubConfig * readConfig(co
1347      }      }
1348   }   }
1349    
1350     if (line->type == LT_DEFAULT && line->numElements == 2) {
1351        cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1352        defaultLine = line;
1353     }
1354    
1355   /* If we find a generic config option which should live at the   /* If we find a generic config option which should live at the
1356     top of the file, move it there. Old versions of grubby were     top of the file, move it there. Old versions of grubby were
1357     probably responsible for putting new images in the wrong     probably responsible for putting new images in the wrong
# Line 1362  static struct grubConfig * readConfig(co Line 1415  static struct grubConfig * readConfig(co
1415      char *defTitle = cfi->getEnv(cfg->cfi, "saved_entry");      char *defTitle = cfi->getEnv(cfg->cfi, "saved_entry");
1416      if (defTitle) {      if (defTitle) {
1417   int index = 0;   int index = 0;
1418   entry = findEntryByTitle(cfg, defTitle, &index);   if (isnumber(defTitle)) {
1419        index = atoi(defTitle);
1420        entry = findEntryByIndex(cfg, index);
1421     } else {
1422        entry = findEntryByTitle(cfg, defTitle, &index);
1423     }
1424   if (entry)   if (entry)
1425      cfg->defaultImage = index;      cfg->defaultImage = index;
1426      }      }
# Line 1395  static struct grubConfig * readConfig(co Line 1453  static struct grubConfig * readConfig(co
1453                                  line->elements[1].item)) break;                                  line->elements[1].item)) break;
1454                  } else if (line) {                  } else if (line) {
1455                      if (!strcmp(defaultLine->elements[1].item,                      if (!strcmp(defaultLine->elements[1].item,
1456                                  extractTitle(line))) break;                                  extractTitle(cfg, line))) break;
1457                  }                  }
1458   i++;   i++;
1459   entry = NULL;   entry = NULL;
# Line 1411  static struct grubConfig * readConfig(co Line 1469  static struct grubConfig * readConfig(co
1469   char *defTitle = cfi->getEnv(cfg->cfi, "saved_entry");   char *defTitle = cfi->getEnv(cfg->cfi, "saved_entry");
1470   if (defTitle) {   if (defTitle) {
1471      int index = 0;      int index = 0;
1472      entry = findEntryByTitle(cfg, defTitle, &index);      if (isnumber(defTitle)) {
1473     index = atoi(defTitle);
1474     entry = findEntryByIndex(cfg, index);
1475        } else {
1476     entry = findEntryByTitle(cfg, defTitle, &index);
1477        }
1478      if (entry)      if (entry)
1479   cfg->defaultImage = index;   cfg->defaultImage = index;
1480   }   }
# Line 1441  static void writeDefault(FILE * out, cha Line 1504  static void writeDefault(FILE * out, cha
1504      if (!line)      if (!line)
1505   line = getLineByType(LT_TITLE, entry->lines);   line = getLineByType(LT_TITLE, entry->lines);
1506      if (line) {      if (line) {
1507   title = extractTitle(line);   title = extractTitle(cfg, line);
1508   if (title)   if (title)
1509      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);
1510      }      }
# Line 1479  static void writeDefault(FILE * out, cha Line 1542  static void writeDefault(FILE * out, cha
1542              else if (line && (line->numElements == 1) &&              else if (line && (line->numElements == 1) &&
1543                       cfg->cfi->titleBracketed) {                       cfg->cfi->titleBracketed) {
1544   fprintf(out, "%sdefault%s%s\n", indent, separator,   fprintf(out, "%sdefault%s%s\n", indent, separator,
1545                          extractTitle(line));                          extractTitle(cfg, line));
1546              }              }
1547   }   }
1548      }      }
# Line 1786  int suitableImage(struct singleEntry * e Line 1849  int suitableImage(struct singleEntry * e
1849   return 0;   return 0;
1850      }      }
1851    
1852      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
1853      if (!line) {      if (!line) {
1854   notSuitablePrintf(entry, 0, "no line found\n");   notSuitablePrintf(entry, 0, "no line found\n");
1855   return 0;   return 0;
# Line 1910  struct singleEntry * findEntryByPath(str Line 1973  struct singleEntry * findEntryByPath(str
1973   }   }
1974    
1975   indexVars[i + 1] = -1;   indexVars[i + 1] = -1;
1976    
1977   i = 0;   i = 0;
1978   if (index) {   if (index) {
1979      while (i < *index) i++;      while (i < *index) {
1980      if (indexVars[i] == -1) return NULL;   i++;
1981     if (indexVars[i] == -1) return NULL;
1982        }
1983   }   }
1984    
1985   entry = findEntryByIndex(config, indexVars[i]);   entry = findEntryByIndex(config, indexVars[i]);
1986   if (!entry) return NULL;   if (!entry) return NULL;
1987    
1988   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
1989   if (!line) return NULL;   if (!line) return NULL;
1990    
1991   if (index) *index = indexVars[i];   if (index) *index = indexVars[i];
# Line 1971  struct singleEntry * findEntryByPath(str Line 2036  struct singleEntry * findEntryByPath(str
2036      for (line = entry->lines; line; line = line->next) {      for (line = entry->lines; line; line = line->next) {
2037   enum lineType_e ct = checkType;   enum lineType_e ct = checkType;
2038   if (entry->multiboot && checkType == LT_KERNEL)   if (entry->multiboot && checkType == LT_KERNEL)
2039      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER;      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER|LT_KERNEL_16;
2040   else if (checkType & LT_KERNEL)   else if (checkType & LT_KERNEL)
2041      ct = checkType | LT_KERNEL_EFI;      ct = checkType | LT_KERNEL_EFI | LT_KERNEL_16;
2042   line = getLineByType(ct, line);   line = getLineByType(ct, line);
2043   if (!line)   if (!line)
2044      break;  /* not found in this entry */      break;  /* not found in this entry */
# Line 1995  struct singleEntry * findEntryByPath(str Line 2060  struct singleEntry * findEntryByPath(str
2060       * non-Linux boot entries (could find netbsd etc, though, which is       * non-Linux boot entries (could find netbsd etc, though, which is
2061       * unfortunate)       * unfortunate)
2062       */       */
2063      if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines))      if (line && getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines))
2064   break; /* found 'im! */   break; /* found 'im! */
2065   }   }
2066    
# Line 2062  struct singleEntry * findTemplate(struct Line 2127  struct singleEntry * findTemplate(struct
2127      char *defTitle = cfg->cfi->getEnv(cfg->cfi, "saved_entry");      char *defTitle = cfg->cfi->getEnv(cfg->cfi, "saved_entry");
2128      if (defTitle) {      if (defTitle) {
2129   int index = 0;   int index = 0;
2130   entry = findEntryByTitle(cfg, defTitle, &index);   if (isnumber(defTitle)) {
2131        index = atoi(defTitle);
2132        entry = findEntryByIndex(cfg, index);
2133     } else {
2134        entry = findEntryByTitle(cfg, defTitle, &index);
2135     }
2136     if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2137        cfg->defaultImage = index;
2138        if (indexPtr)
2139     *indexPtr = index;
2140        return entry;
2141     }
2142      }      }
2143   }   }
2144      } else if (cfg->defaultImage > -1) {      } else if (cfg->defaultImage > -1) {
# Line 2219  void displayEntry(struct singleEntry * e Line 2295  void displayEntry(struct singleEntry * e
2295      struct singleLine * line;      struct singleLine * line;
2296      char * root = NULL;      char * root = NULL;
2297      int i;      int i;
2298        int j;
2299    
2300      printf("index=%d\n", index);      printf("index=%d\n", index);
2301    
2302      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
2303      if (!line) {      if (!line) {
2304          printf("non linux entry\n");          printf("non linux entry\n");
2305          return;          return;
# Line 2287  void displayEntry(struct singleEntry * e Line 2364  void displayEntry(struct singleEntry * e
2364   printf("root=%s\n", s);   printf("root=%s\n", s);
2365      }      }
2366    
2367      line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines);      line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
2368    
2369      if (line && line->numElements >= 2) {      if (line && line->numElements >= 2) {
2370   if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))   if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
# Line 2306  void displayEntry(struct singleEntry * e Line 2383  void displayEntry(struct singleEntry * e
2383      } else {      } else {
2384   char * title;   char * title;
2385   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
2386   title = grub2ExtractTitle(line);   if (line) {
2387   if (title)      title = grub2ExtractTitle(line);
2388      printf("title=%s\n", title);      if (title)
2389     printf("title=%s\n", title);
2390     }
2391        }
2392    
2393        for (j = 0, line = entry->lines; line; line = line->next) {
2394     if ((line->type & LT_MBMODULE) && line->numElements >= 2) {
2395        if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
2396     printf("mbmodule%d=", j);
2397        else
2398     printf("mbmodule%d=%s", j, prefix);
2399    
2400        for (i = 1; i < line->numElements; i++)
2401     printf("%s%s", line->elements[i].item, line->elements[i].indent);
2402        printf("\n");
2403        j++;
2404     }
2405      }      }
2406  }  }
2407    
# Line 2704  struct singleLine * addLineTmpl(struct s Line 2797  struct singleLine * addLineTmpl(struct s
2797   insertElement(newLine, val, 1, cfi);   insertElement(newLine, val, 1, cfi);
2798    
2799   /* but try to keep the rootspec from the template... sigh */   /* but try to keep the rootspec from the template... sigh */
2800   if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI)) {   if (tmplLine->type & (LT_HYPER|LT_KERNEL|LT_MBMODULE|LT_INITRD|LT_KERNEL_EFI|LT_INITRD_EFI|LT_KERNEL_16|LT_INITRD_16)) {
2801      char * rootspec = getRootSpecifier(tmplLine->elements[1].item);      char * rootspec = getRootSpecifier(tmplLine->elements[1].item);
2802      if (rootspec != NULL) {      if (rootspec != NULL) {
2803   free(newLine->elements[1].item);   free(newLine->elements[1].item);
# Line 3074  int updateActualImage(struct grubConfig Line 3167  int updateActualImage(struct grubConfig
3167      firstElement = 2;      firstElement = 2;
3168    
3169   } else {   } else {
3170      line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_MBMODULE|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3171      if (!line) {      if (!line) {
3172   /* no LT_KERNEL or LT_MBMODULE in this entry? */   /* no LT_KERNEL or LT_MBMODULE in this entry? */
3173   continue;   continue;
# Line 3230  int updateImage(struct grubConfig * cfg, Line 3323  int updateImage(struct grubConfig * cfg,
3323      return rc;      return rc;
3324  }  }
3325    
3326    int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,
3327     const char * image, const char * prefix, const char * initrd,
3328     const char * title) {
3329        struct singleEntry * entry;
3330        struct singleLine * line, * kernelLine, *endLine = NULL;
3331        int index = 0;
3332    
3333        if (!image) return 0;
3334    
3335        for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3336            kernelLine = getLineByType(LT_MBMODULE, entry->lines);
3337            if (!kernelLine) continue;
3338    
3339     /* if title is supplied, the entry's title must match it. */
3340     if (title) {
3341        char *linetitle;
3342    
3343        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3344        if (!line)
3345     continue;
3346    
3347        linetitle = extractTitle(cfg, line);
3348        if (!linetitle)
3349     continue;
3350        if (strcmp(title, linetitle)) {
3351     free(linetitle);
3352     continue;
3353        }
3354        free(linetitle);
3355     }
3356    
3357            if (prefix) {
3358                int prefixLen = strlen(prefix);
3359                if (!strncmp(initrd, prefix, prefixLen))
3360                    initrd += prefixLen;
3361            }
3362     endLine = getLineByType(LT_ENTRY_END, entry->lines);
3363     if (endLine)
3364        removeLine(entry, endLine);
3365            line = addLine(entry, cfg->cfi, preferredLineType(LT_MBMODULE,cfg->cfi),
3366     kernelLine->indent, initrd);
3367            if (!line)
3368        return 1;
3369     if (endLine) {
3370        line = addLine(entry, cfg->cfi, LT_ENTRY_END, "", NULL);
3371                if (!line)
3372     return 1;
3373     }
3374    
3375            break;
3376        }
3377    
3378        return 0;
3379    }
3380    
3381  int updateInitrd(struct grubConfig * cfg, const char * image,  int updateInitrd(struct grubConfig * cfg, const char * image,
3382                   const char * prefix, const char * initrd) {                   const char * prefix, const char * initrd, const char * title) {
3383      struct singleEntry * entry;      struct singleEntry * entry;
3384      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3385      int index = 0;      int index = 0;
# Line 3239  int updateInitrd(struct grubConfig * cfg Line 3387  int updateInitrd(struct grubConfig * cfg
3387      if (!image) return 0;      if (!image) return 0;
3388    
3389      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3390          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI, entry->lines);          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3391          if (!kernelLine) continue;          if (!kernelLine) continue;
3392    
3393          line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines);   /* if title is supplied, the entry's title must match it. */
3394     if (title) {
3395        char *linetitle;
3396    
3397        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3398        if (!line)
3399     continue;
3400    
3401        linetitle = extractTitle(cfg, line);
3402        if (!linetitle)
3403     continue;
3404        if (strcmp(title, linetitle)) {
3405     free(linetitle);
3406     continue;
3407        }
3408        free(linetitle);
3409     }
3410    
3411            line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
3412          if (line)          if (line)
3413              removeLine(entry, line);              removeLine(entry, line);
3414          if (prefix) {          if (prefix) {
# Line 3253  int updateInitrd(struct grubConfig * cfg Line 3419  int updateInitrd(struct grubConfig * cfg
3419   endLine = getLineByType(LT_ENTRY_END, entry->lines);   endLine = getLineByType(LT_ENTRY_END, entry->lines);
3420   if (endLine)   if (endLine)
3421      removeLine(entry, endLine);      removeLine(entry, endLine);
3422          line = addLine(entry, cfg->cfi, preferredLineType(LT_INITRD, cfg->cfi),   enum lineType_e lt;
3423   kernelLine->indent, initrd);   switch(kernelLine->type) {
3424        case LT_KERNEL:
3425            lt = LT_INITRD;
3426     break;
3427        case LT_KERNEL_EFI:
3428            lt = LT_INITRD_EFI;
3429     break;
3430        case LT_KERNEL_16:
3431            lt = LT_INITRD_16;
3432     break;
3433        default:
3434            lt = preferredLineType(LT_INITRD, cfg->cfi);
3435     }
3436            line = addLine(entry, cfg->cfi, lt, kernelLine->indent, initrd);
3437          if (!line)          if (!line)
3438      return 1;      return 1;
3439   if (endLine) {   if (endLine) {
# Line 3613  int addNewKernel(struct grubConfig * con Line 3792  int addNewKernel(struct grubConfig * con
3792   const char * newKernelPath, const char * newKernelTitle,   const char * newKernelPath, const char * newKernelTitle,
3793   const char * newKernelArgs, const char * newKernelInitrd,   const char * newKernelArgs, const char * newKernelInitrd,
3794   const char ** extraInitrds, int extraInitrdCount,   const char ** extraInitrds, int extraInitrdCount,
3795                   const char * newMBKernel, const char * newMBKernelArgs) {                   const char * newMBKernel, const char * newMBKernelArgs,
3796     const char * newDevTreePath) {
3797      struct singleEntry * new;      struct singleEntry * new;
3798      struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL;      struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL;
3799      int needs;      int needs;
# Line 3654  int addNewKernel(struct grubConfig * con Line 3834  int addNewKernel(struct grubConfig * con
3834          needs |= NEED_MB;          needs |= NEED_MB;
3835          new->multiboot = 1;          new->multiboot = 1;
3836      }      }
3837        if (newDevTreePath && getKeywordByType(LT_DEVTREE, config->cfi))
3838     needs |= NEED_DEVTREE;
3839    
3840      if (template) {      if (template) {
3841   for (masterLine = template->lines;   for (masterLine = template->lines;
# Line 3839  int addNewKernel(struct grubConfig * con Line 4021  int addNewKernel(struct grubConfig * con
4021   newLine = addLineTmpl(new, tmplLine, newLine, NULL,   newLine = addLineTmpl(new, tmplLine, newLine, NULL,
4022   config->cfi);   config->cfi);
4023      }      }
4024        } else if (tmplLine->type == LT_DEVTREE &&
4025           tmplLine->numElements == 2 && newDevTreePath) {
4026            newLine = addLineTmpl(new, tmplLine, newLine,
4027          newDevTreePath + strlen(prefix),
4028          config->cfi);
4029     needs &= ~NEED_DEVTREE;
4030        } else if (tmplLine->type == LT_ENTRY_END && needs & NEED_DEVTREE) {
4031     const char *ndtp = newDevTreePath;
4032     if (!strncmp(newDevTreePath, prefix, strlen(prefix)))
4033        ndtp += strlen(prefix);
4034     newLine = addLine(new, config->cfi, LT_DEVTREE,
4035      config->secondaryIndent,
4036      ndtp);
4037     needs &= ~NEED_DEVTREE;
4038     newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);
4039      } else {      } else {
4040   /* pass through other lines from the template */   /* pass through other lines from the template */
4041   newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);   newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);
# Line 3852  int addNewKernel(struct grubConfig * con Line 4049  int addNewKernel(struct grubConfig * con
4049   switch (config->cfi->entryStart) {   switch (config->cfi->entryStart) {
4050      case LT_KERNEL:      case LT_KERNEL:
4051      case LT_KERNEL_EFI:      case LT_KERNEL_EFI:
4052        case LT_KERNEL_16:
4053   if (new->multiboot && config->cfi->mbHyperFirst) {   if (new->multiboot && config->cfi->mbHyperFirst) {
4054      /* fall through to LT_HYPER */      /* fall through to LT_HYPER */
4055   } else {   } else {
# Line 3913  int addNewKernel(struct grubConfig * con Line 4111  int addNewKernel(struct grubConfig * con
4111   }   }
4112      }      }
4113    
4114        struct singleLine *endLine = NULL;
4115        endLine = getLineByType(LT_ENTRY_END, new->lines);
4116        if (endLine) {
4117        removeLine(new, endLine);
4118        needs |= NEED_END;
4119        }
4120    
4121      /* add the remainder of the lines, i.e. those that either      /* add the remainder of the lines, i.e. those that either
4122       * weren't present in the template, or in the case of no template,       * weren't present in the template, or in the case of no template,
4123       * all the lines following the entryStart.       * all the lines following the entryStart.
# Line 3958  int addNewKernel(struct grubConfig * con Line 4163  int addNewKernel(struct grubConfig * con
4163   free(initrdVal);   free(initrdVal);
4164   needs &= ~NEED_INITRD;   needs &= ~NEED_INITRD;
4165      }      }
4166        if (needs & NEED_DEVTREE) {
4167     newLine = addLine(new, config->cfi, LT_DEVTREE,
4168      config->secondaryIndent,
4169      newDevTreePath);
4170     needs &= ~NEED_DEVTREE;
4171        }
4172    
4173        /* NEEDS_END must be last on bootloaders that need it... */
4174      if (needs & NEED_END) {      if (needs & NEED_END) {
4175   newLine = addLine(new, config->cfi, LT_ENTRY_END,   newLine = addLine(new, config->cfi, LT_ENTRY_END,
4176   config->secondaryIndent, NULL);   config->secondaryIndent, NULL);
# Line 4009  int main(int argc, const char ** argv) { Line 4222  int main(int argc, const char ** argv) {
4222      char * newKernelArgs = NULL;      char * newKernelArgs = NULL;
4223      char * newKernelInitrd = NULL;      char * newKernelInitrd = NULL;
4224      char * newKernelTitle = NULL;      char * newKernelTitle = NULL;
4225      char * newKernelVersion = NULL;      char * newDevTreePath = NULL;
4226      char * newMBKernel = NULL;      char * newMBKernel = NULL;
4227      char * newMBKernelArgs = NULL;      char * newMBKernelArgs = NULL;
4228      char * removeMBKernelArgs = NULL;      char * removeMBKernelArgs = NULL;
# Line 4067  int main(int argc, const char ** argv) { Line 4280  int main(int argc, const char ** argv) {
4280      _("display the index of the default kernel") },      _("display the index of the default kernel") },
4281   { "default-title", 0, 0, &displayDefaultTitle, 0,   { "default-title", 0, 0, &displayDefaultTitle, 0,
4282      _("display the title of the default kernel") },      _("display the title of the default kernel") },
4283     { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4284        _("device tree file for new stanza"), _("dtb-path") },
4285     { "devtreedir", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4286        _("device tree directory for new stanza"), _("dtb-path") },
4287   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,
4288      _("configure elilo bootloader") },      _("configure elilo bootloader") },
4289   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,
# Line 4207  int main(int argc, const char ** argv) { Line 4424  int main(int argc, const char ** argv) {
4424      }      }
4425    
4426      if (!cfi) {      if (!cfi) {
4427          if (grub2FindConfig(&grub2ConfigType))          if (grub2FindConfig(&grub2ConfigType)) {
4428      cfi = &grub2ConfigType;      cfi = &grub2ConfigType;
4429   else      if (envPath)
4430     cfi->envFile = envPath;
4431            } else
4432        #ifdef __ia64__        #ifdef __ia64__
4433      cfi = &eliloConfigType;      cfi = &eliloConfigType;
4434        #elif __powerpc__        #elif __powerpc__
# Line 4232  int main(int argc, const char ** argv) { Line 4451  int main(int argc, const char ** argv) {
4451      grubConfig = cfi->defaultConfig;      grubConfig = cfi->defaultConfig;
4452      }      }
4453    
4454      if (bootloaderProbe && (displayDefault || kernelInfo || newKernelVersion ||      if (bootloaderProbe && (displayDefault || kernelInfo ||
4455      newKernelPath || removeKernelPath || makeDefault ||      newKernelPath || removeKernelPath || makeDefault ||
4456      defaultKernel || displayDefaultIndex || displayDefaultTitle ||      defaultKernel || displayDefaultIndex || displayDefaultTitle ||
4457      (defaultIndex >= 0))) {      (defaultIndex >= 0))) {
# Line 4241  int main(int argc, const char ** argv) { Line 4460  int main(int argc, const char ** argv) {
4460   return 1;   return 1;
4461      }      }
4462    
4463      if ((displayDefault || kernelInfo) && (newKernelVersion || newKernelPath ||      if ((displayDefault || kernelInfo) && (newKernelPath ||
4464     removeKernelPath)) {     removeKernelPath)) {
4465   fprintf(stderr, _("grubby: --default-kernel and --info may not "   fprintf(stderr, _("grubby: --default-kernel and --info may not "
4466    "be used when adding or removing kernels\n"));    "be used when adding or removing kernels\n"));
# Line 4251  int main(int argc, const char ** argv) { Line 4470  int main(int argc, const char ** argv) {
4470      if (newKernelPath && !newKernelTitle) {      if (newKernelPath && !newKernelTitle) {
4471   fprintf(stderr, _("grubby: kernel title must be specified\n"));   fprintf(stderr, _("grubby: kernel title must be specified\n"));
4472   return 1;   return 1;
4473      } else if (!newKernelPath && (newKernelTitle  || copyDefault ||      } else if (!newKernelPath && (copyDefault ||
4474    (newKernelInitrd && !updateKernelPath)||    (newKernelInitrd && !updateKernelPath)||
4475    makeDefault || extraInitrdCount > 0)) {    makeDefault || extraInitrdCount > 0)) {
4476   fprintf(stderr, _("grubby: kernel path expected\n"));   fprintf(stderr, _("grubby: kernel path expected\n"));
# Line 4410  int main(int argc, const char ** argv) { Line 4629  int main(int argc, const char ** argv) {
4629   if (!entry) return 0;   if (!entry) return 0;
4630   if (!suitableImage(entry, bootPrefix, 0, flags)) return 0;   if (!suitableImage(entry, bootPrefix, 0, flags)) return 0;
4631    
4632   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);   line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
4633   if (!line) return 0;   if (!line) return 0;
4634    
4635          rootspec = getRootSpecifier(line->elements[1].item);          rootspec = getRootSpecifier(line->elements[1].item);
# Line 4471  int main(int argc, const char ** argv) { Line 4690  int main(int argc, const char ** argv) {
4690      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
4691                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;
4692      if (updateKernelPath && newKernelInitrd) {      if (updateKernelPath && newKernelInitrd) {
4693              if (updateInitrd(config, updateKernelPath, bootPrefix,      if (newMBKernel) {
4694                               newKernelInitrd)) return 1;      if (addMBInitrd(config, newMBKernel, updateKernelPath,
4695     bootPrefix, newKernelInitrd,
4696     newKernelTitle))
4697        return 1;
4698        } else {
4699        if (updateInitrd(config, updateKernelPath, bootPrefix,
4700     newKernelInitrd, newKernelTitle))
4701     return 1;
4702        }
4703      }      }
4704      if (addNewKernel(config, template, bootPrefix, newKernelPath,      if (addNewKernel(config, template, bootPrefix, newKernelPath,
4705                       newKernelTitle, newKernelArgs, newKernelInitrd,                       newKernelTitle, newKernelArgs, newKernelInitrd,
4706                       (const char **)extraInitrds, extraInitrdCount,                       (const char **)extraInitrds, extraInitrdCount,
4707                       newMBKernel, newMBKernelArgs)) return 1;                       newMBKernel, newMBKernelArgs, newDevTreePath)) return 1;
4708            
4709    
4710      if (numEntries(config) == 0) {      if (numEntries(config) == 0) {

Legend:
Removed from v.2257  
changed lines
  Added in v.2986