Magellan Linux

Diff of /tags/grubby-8_40_20170627/grubby.c

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

revision 2246 by niro, Mon Oct 21 13:53:05 2013 UTC revision 2972 by niro, Thu Jun 30 10:17:00 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 136  struct configFileInfo; Line 146  struct configFileInfo;
146  typedef const char *(*findConfigFunc)(struct configFileInfo *);  typedef const char *(*findConfigFunc)(struct configFileInfo *);
147  typedef const int (*writeLineFunc)(struct configFileInfo *,  typedef const int (*writeLineFunc)(struct configFileInfo *,
148   struct singleLine *line);   struct singleLine *line);
149    typedef char *(*getEnvFunc)(struct configFileInfo *, char *name);
150    typedef int (*setEnvFunc)(struct configFileInfo *, char *name, char *value);
151    
152  struct configFileInfo {  struct configFileInfo {
153      char * defaultConfig;      char * defaultConfig;
154      findConfigFunc findConfig;      findConfigFunc findConfig;
155      writeLineFunc writeLine;      writeLineFunc writeLine;
156        getEnvFunc getEnv;
157        setEnvFunc setEnv;
158      struct keywordTypes * keywords;      struct keywordTypes * keywords;
159      int caseInsensitive;      int caseInsensitive;
160      int defaultIsIndex;      int defaultIsIndex;
161      int defaultIsVariable;      int defaultIsVariable;
162      int defaultSupportSaved;      int defaultSupportSaved;
163        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 157  struct configFileInfo { Line 173  struct configFileInfo {
173      int mbInitRdIsModule;      int mbInitRdIsModule;
174      int mbConcatArgs;      int mbConcatArgs;
175      int mbAllowExtraInitRds;      int mbAllowExtraInitRds;
176        char *envFile;
177  };  };
178    
179  struct keywordTypes grubKeywords[] = {  struct keywordTypes grubKeywords[] = {
# Line 176  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 215  struct keywordTypes grub2Keywords[] = { Line 234  struct keywordTypes grub2Keywords[] = {
234      { "fallback",   LT_FALLBACK,    ' ' },      { "fallback",   LT_FALLBACK,    ' ' },
235      { "linux",      LT_KERNEL,      ' ' },      { "linux",      LT_KERNEL,      ' ' },
236      { "linuxefi",   LT_KERNEL_EFI,  ' ' },      { "linuxefi",   LT_KERNEL_EFI,  ' ' },
237        { "linux16",    LT_KERNEL_16,   ' ' },
238      { "initrd",     LT_INITRD,      ' ', ' ' },      { "initrd",     LT_INITRD,      ' ', ' ' },
239      { "initrdefi",  LT_INITRD_EFI,  ' ', ' ' },      { "initrdefi",  LT_INITRD_EFI,  ' ', ' ' },
240        { "initrd16",   LT_INITRD_16,   ' ', ' ' },
241      { "module",     LT_MBMODULE,    ' ' },      { "module",     LT_MBMODULE,    ' ' },
242      { "kernel",     LT_HYPER,       ' ' },      { "kernel",     LT_HYPER,       ' ' },
243        { "devicetree", LT_DEVTREE,  ' ' },
244      { NULL, 0, 0 },      { NULL, 0, 0 },
245  };  };
246    
# Line 261  const char *grub2FindConfig(struct confi Line 283  const char *grub2FindConfig(struct confi
283      return configFiles[i];      return configFiles[i];
284  }  }
285    
286    /* kind of hacky.  It'll give the first 1024 bytes, ish. */
287    static char *grub2GetEnv(struct configFileInfo *info, char *name)
288    {
289        static char buf[1025];
290        char *s = NULL;
291        char *ret = NULL;
292        char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv";
293        int rc = asprintf(&s, "grub-editenv %s list | grep '^%s='", envFile, name);
294    
295        if (rc < 0)
296     return NULL;
297    
298        FILE *f = popen(s, "r");
299        if (!f)
300     goto out;
301    
302        memset(buf, '\0', sizeof (buf));
303        ret = fgets(buf, 1024, f);
304        pclose(f);
305    
306        if (ret) {
307     ret += strlen(name) + 1;
308     ret[strlen(ret) - 1] = '\0';
309        }
310        dbgPrintf("grub2GetEnv(%s): %s\n", name, ret);
311    out:
312        free(s);
313        return ret;
314    }
315    
316    static int sPopCount(const char *s, const char *c)
317    {
318        int ret = 0;
319        if (!s)
320     return -1;
321        for (int i = 0; s[i] != '\0'; i++)
322     for (int j = 0; c[j] != '\0'; j++)
323        if (s[i] == c[j])
324     ret++;
325        return ret;
326    }
327    
328    static char *shellEscape(const char *s)
329    {
330        int l = strlen(s) + sPopCount(s, "'") * 2;
331    
332        char *ret = calloc(l+1, sizeof (*ret));
333        if (!ret)
334     return NULL;
335        for (int i = 0, j = 0; s[i] != '\0'; i++, j++) {
336     if (s[i] == '\'')
337        ret[j++] = '\\';
338     ret[j] = s[i];
339        }
340        return ret;
341    }
342    
343    static void unquote(char *s)
344    {
345        int l = strlen(s);
346    
347        if ((s[l-1] == '\'' && s[0] == '\'') || (s[l-1] == '"' && s[0] == '"')) {
348     memmove(s, s+1, l-2);
349     s[l-2] = '\0';
350        }
351    }
352    
353    static int grub2SetEnv(struct configFileInfo *info, char *name, char *value)
354    {
355        char *s = NULL;
356        int rc = 0;
357        char *envFile = info->envFile ? info->envFile : "/boot/grub/grubenv";
358    
359        unquote(value);
360        value = shellEscape(value);
361        if (!value)
362        return -1;
363    
364        rc = asprintf(&s, "grub-editenv %s set '%s=%s'", envFile, name, value);
365        free(value);
366        if (rc <0)
367     return -1;
368    
369        dbgPrintf("grub2SetEnv(%s): %s\n", name, s);
370        rc = system(s);
371        free(s);
372        return rc;
373    }
374    
375    /* this is a gigantic hack to avoid clobbering grub2 variables... */
376    static int is_special_grub2_variable(const char *name)
377    {
378        if (!strcmp(name,"\"${next_entry}\""))
379     return 1;
380        if (!strcmp(name,"\"${prev_saved_entry}\""))
381     return 1;
382        return 0;
383    }
384    
385  int sizeOfSingleLine(struct singleLine * line) {  int sizeOfSingleLine(struct singleLine * line) {
386    int count = 0;    int count = 0;
387    
# Line 291  static int isquote(char q) Line 412  static int isquote(char q)
412  }  }
413    
414  static int iskernel(enum lineType_e type) {  static int iskernel(enum lineType_e type) {
415      return (type == LT_KERNEL || type == LT_KERNEL_EFI);      return (type == LT_KERNEL || type == LT_KERNEL_EFI || type == LT_KERNEL_16);
416  }  }
417    
418  static int isinitrd(enum lineType_e type) {  static int isinitrd(enum lineType_e type) {
419      return (type == LT_INITRD || type == LT_INITRD_EFI);      return (type == LT_INITRD || type == LT_INITRD_EFI || type == LT_INITRD_16);
420  }  }
421    
422  char *grub2ExtractTitle(struct singleLine * line) {  char *grub2ExtractTitle(struct singleLine * line) {
# Line 355  char *grub2ExtractTitle(struct singleLin Line 476  char *grub2ExtractTitle(struct singleLin
476    
477  struct configFileInfo grub2ConfigType = {  struct configFileInfo grub2ConfigType = {
478      .findConfig = grub2FindConfig,      .findConfig = grub2FindConfig,
479        .getEnv = grub2GetEnv,
480        .setEnv = grub2SetEnv,
481      .keywords = grub2Keywords,      .keywords = grub2Keywords,
482      .defaultIsIndex = 1,      .defaultIsIndex = 1,
483      .defaultSupportSaved = 1,      .defaultSupportSaved = 1,
# Line 459  struct keywordTypes extlinuxKeywords[] = Line 582  struct keywordTypes extlinuxKeywords[] =
582      { "initrd",    LT_INITRD,      ' ', ',' },      { "initrd",    LT_INITRD,      ' ', ',' },
583      { "append",    LT_KERNELARGS,  ' ' },      { "append",    LT_KERNELARGS,  ' ' },
584      { "prompt",     LT_UNKNOWN,     ' ' },      { "prompt",     LT_UNKNOWN,     ' ' },
585        { "fdt",        LT_DEVTREE,     ' ' },
586        { "fdtdir",     LT_DEVTREE,     ' ' },
587      { NULL,    0, 0 },      { NULL,    0, 0 },
588  };  };
589  int useextlinuxmenu;  int useextlinuxmenu;
# Line 514  struct configFileInfo extlinuxConfigType Line 639  struct configFileInfo extlinuxConfigType
639      .needsBootPrefix = 1,      .needsBootPrefix = 1,
640      .maxTitleLength = 255,      .maxTitleLength = 255,
641      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
642        .defaultIsUnquoted = 1,
643  };  };
644    
645  struct grubConfig {  struct grubConfig {
# Line 534  struct singleEntry * findEntryByIndex(st Line 660  struct singleEntry * findEntryByIndex(st
660  struct singleEntry * findEntryByPath(struct grubConfig * cfg,  struct singleEntry * findEntryByPath(struct grubConfig * cfg,
661       const char * path, const char * prefix,       const char * path, const char * prefix,
662       int * index);       int * index);
663    struct singleEntry * findEntryByTitle(struct grubConfig * cfg, char *title,
664          int * index);
665  static int readFile(int fd, char ** bufPtr);  static int readFile(int fd, char ** bufPtr);
666  static void lineInit(struct singleLine * line);  static void lineInit(struct singleLine * line);
667  struct singleLine * lineDup(struct singleLine * line);  struct singleLine * lineDup(struct singleLine * line);
# Line 603  static enum lineType_e preferredLineType Line 731  static enum lineType_e preferredLineType
731      if (isEfi && cfi == &grub2ConfigType) {      if (isEfi && cfi == &grub2ConfigType) {
732   switch (type) {   switch (type) {
733   case LT_KERNEL:   case LT_KERNEL:
734      return LT_KERNEL_EFI;      return isEfiOnly ? LT_KERNEL : LT_KERNEL_EFI;
735   case LT_INITRD:   case LT_INITRD:
736      return LT_INITRD_EFI;      return isEfiOnly ? LT_INITRD : LT_INITRD_EFI;
737   default:   default:
738      return type;      return type;
739   }   }
740    #if defined(__i386__) || defined(__x86_64__)
741        } else if (cfi == &grub2ConfigType) {
742     switch (type) {
743     case LT_KERNEL:
744        return LT_KERNEL_16;
745     case LT_INITRD:
746        return LT_INITRD_16;
747     default:
748        return type;
749     }
750    #endif
751      }      }
752      return type;      return type;
753  }  }
# Line 691  static int isEntryStart(struct singleLin Line 830  static int isEntryStart(struct singleLin
830  /* extract the title from within brackets (for zipl) */  /* extract the title from within brackets (for zipl) */
831  static char * extractTitle(struct singleLine * line) {  static char * extractTitle(struct singleLine * line) {
832      /* bracketed title... let's extract it (leaks a byte) */      /* bracketed title... let's extract it (leaks a byte) */
833      char * title;      char * title = NULL;
834      title = strdup(line->elements[0].item);      if (line->type == LT_TITLE) {
835      title++;   title = strdup(line->elements[0].item);
836      *(title + strlen(title) - 1) = '\0';   title++;
837     *(title + strlen(title) - 1) = '\0';
838        } else if (line->type == LT_MENUENTRY)
839     title = strdup(line->elements[1].item);
840        else
841     return NULL;
842      return title;      return title;
843  }  }
844    
# Line 952  static int getNextLine(char ** bufPtr, s Line 1096  static int getNextLine(char ** bufPtr, s
1096      return 0;      return 0;
1097  }  }
1098    
1099    static int isnumber(const char *s)
1100    {
1101        int i;
1102        for (i = 0; s[i] != '\0'; i++)
1103     if (s[i] < '0' || s[i] > '9')
1104        return 0;
1105        return i;
1106    }
1107    
1108  static struct grubConfig * readConfig(const char * inName,  static struct grubConfig * readConfig(const char * inName,
1109        struct configFileInfo * cfi) {        struct configFileInfo * cfi) {
1110      int in;      int in;
# Line 1036  static struct grubConfig * readConfig(co Line 1189  static struct grubConfig * readConfig(co
1189      dbgPrintf("\n");      dbgPrintf("\n");
1190      struct keywordTypes *kwType = getKeywordByType(LT_DEFAULT, cfi);      struct keywordTypes *kwType = getKeywordByType(LT_DEFAULT, cfi);
1191      if (kwType && line->numElements == 3 &&      if (kwType && line->numElements == 3 &&
1192      !strcmp(line->elements[1].item, kwType->key)) {      !strcmp(line->elements[1].item, kwType->key) &&
1193        !is_special_grub2_variable(line->elements[2].item)) {
1194   dbgPrintf("Line sets default config\n");   dbgPrintf("Line sets default config\n");
1195   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1196   defaultLine = line;   defaultLine = line;
1197      }      }
  } else if (line->type == LT_DEFAULT && line->numElements == 2) {  
     cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;  
     defaultLine = line;  
1198    
1199          } else if (iskernel(line->type)) {          } else if (iskernel(line->type)) {
1200      /* if by some freak chance this is multiboot and the "module"      /* if by some freak chance this is multiboot and the "module"
1201       * lines came earlier in the template, make sure to use LT_HYPER       * lines came earlier in the template, make sure to use LT_HYPER
1202       * instead of LT_KERNEL now       * instead of LT_KERNEL now
1203       */       */
1204      if (entry->multiboot)      if (entry && entry->multiboot)
1205   line->type = LT_HYPER;   line->type = LT_HYPER;
1206    
1207          } else if (line->type == LT_MBMODULE) {          } else if (line->type == LT_MBMODULE) {
# Line 1076  static struct grubConfig * readConfig(co Line 1227  static struct grubConfig * readConfig(co
1227      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);
1228      if (*end) cfg->fallbackImage = -1;      if (*end) cfg->fallbackImage = -1;
1229    
1230   } else if (line->type == LT_TITLE && line->numElements > 1) {   } else if ((line->type == LT_DEFAULT && cfi->defaultIsUnquoted) ||
1231      /* make the title a single argument (undoing our parsing) */                  (line->type == LT_TITLE && line->numElements > 1)) {
1232        /* make the title/default a single argument (undoing our parsing) */
1233      len = 0;      len = 0;
1234      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1235   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1184  static struct grubConfig * readConfig(co Line 1336  static struct grubConfig * readConfig(co
1336      }      }
1337   }   }
1338    
1339     if (line->type == LT_DEFAULT && line->numElements == 2) {
1340        cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1341        defaultLine = line;
1342     }
1343    
1344   /* If we find a generic config option which should live at the   /* If we find a generic config option which should live at the
1345     top of the file, move it there. Old versions of grubby were     top of the file, move it there. Old versions of grubby were
1346     probably responsible for putting new images in the wrong     probably responsible for putting new images in the wrong
# Line 1241  static struct grubConfig * readConfig(co Line 1398  static struct grubConfig * readConfig(co
1398          if (defaultLine->numElements > 2 &&          if (defaultLine->numElements > 2 &&
1399      cfi->defaultSupportSaved &&      cfi->defaultSupportSaved &&
1400      !strncmp(defaultLine->elements[2].item,"\"${saved_entry}\"", 16)) {      !strncmp(defaultLine->elements[2].item,"\"${saved_entry}\"", 16)) {
1401      cfg->defaultImage = DEFAULT_SAVED_GRUB2;   cfg->cfi->defaultIsSaved = 1;
1402     cfg->defaultImage = DEFAULT_SAVED_GRUB2;
1403     if (cfg->cfi->getEnv) {
1404        char *defTitle = cfi->getEnv(cfg->cfi, "saved_entry");
1405        if (defTitle) {
1406     int index = 0;
1407     if (isnumber(defTitle)) {
1408        index = atoi(defTitle);
1409        entry = findEntryByIndex(cfg, index);
1410     } else {
1411        entry = findEntryByTitle(cfg, defTitle, &index);
1412     }
1413     if (entry)
1414        cfg->defaultImage = index;
1415        }
1416     }
1417   } else if (cfi->defaultIsVariable) {   } else if (cfi->defaultIsVariable) {
1418      char *value = defaultLine->elements[2].item;      char *value = defaultLine->elements[2].item;
1419      while (*value && (*value == '"' || *value == '\'' ||      while (*value && (*value == '"' || *value == '\'' ||
# Line 1282  static struct grubConfig * readConfig(co Line 1454  static struct grubConfig * readConfig(co
1454          cfg->defaultImage = -1;          cfg->defaultImage = -1;
1455      }      }
1456   }   }
1457        } else if (cfg->cfi->defaultIsSaved && cfg->cfi->getEnv) {
1458     char *defTitle = cfi->getEnv(cfg->cfi, "saved_entry");
1459     if (defTitle) {
1460        int index = 0;
1461        if (isnumber(defTitle)) {
1462     index = atoi(defTitle);
1463     entry = findEntryByIndex(cfg, index);
1464        } else {
1465     entry = findEntryByTitle(cfg, defTitle, &index);
1466        }
1467        if (entry)
1468     cfg->defaultImage = index;
1469     }
1470      } else {      } else {
1471          cfg->defaultImage = 0;          cfg->defaultImage = 0;
1472      }      }
# Line 1299  static void writeDefault(FILE * out, cha Line 1484  static void writeDefault(FILE * out, cha
1484    
1485      if (cfg->defaultImage == DEFAULT_SAVED)      if (cfg->defaultImage == DEFAULT_SAVED)
1486   fprintf(out, "%sdefault%ssaved\n", indent, separator);   fprintf(out, "%sdefault%ssaved\n", indent, separator);
1487      else if (cfg->defaultImage == DEFAULT_SAVED_GRUB2)      else if (cfg->cfi->defaultIsSaved) {
1488   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);
1489      else if (cfg->defaultImage > -1) {   if (cfg->defaultImage >= 0 && cfg->cfi->setEnv) {
1490        char *title;
1491        entry = findEntryByIndex(cfg, cfg->defaultImage);
1492        line = getLineByType(LT_MENUENTRY, entry->lines);
1493        if (!line)
1494     line = getLineByType(LT_TITLE, entry->lines);
1495        if (line) {
1496     title = extractTitle(line);
1497     if (title)
1498        cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);
1499        }
1500     }
1501        } else if (cfg->defaultImage > -1) {
1502   if (cfg->cfi->defaultIsIndex) {   if (cfg->cfi->defaultIsIndex) {
1503      if (cfg->cfi->defaultIsVariable) {      if (cfg->cfi->defaultIsVariable) {
1504          fprintf(out, "%sset default=\"%d\"\n", indent,          fprintf(out, "%sset default=\"%d\"\n", indent,
# Line 1404  static int writeConfig(struct grubConfig Line 1601  static int writeConfig(struct grubConfig
1601      while (line) {      while (line) {
1602          if (line->type == LT_SET_VARIABLE && defaultKw &&          if (line->type == LT_SET_VARIABLE && defaultKw &&
1603   line->numElements == 3 &&   line->numElements == 3 &&
1604   !strcmp(line->elements[1].item, defaultKw->key)) {   !strcmp(line->elements[1].item, defaultKw->key) &&
1605     !is_special_grub2_variable(line->elements[2].item)) {
1606      writeDefault(out, line->indent, line->elements[0].indent, cfg);      writeDefault(out, line->indent, line->elements[0].indent, cfg);
1607      needs &= ~MAIN_DEFAULT;      needs &= ~MAIN_DEFAULT;
1608   } else if (line->type == LT_DEFAULT) {   } else if (line->type == LT_DEFAULT) {
# Line 1640  int suitableImage(struct singleEntry * e Line 1838  int suitableImage(struct singleEntry * e
1838   return 0;   return 0;
1839      }      }
1840    
1841      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);
1842      if (!line) {      if (!line) {
1843   notSuitablePrintf(entry, 0, "no line found\n");   notSuitablePrintf(entry, 0, "no line found\n");
1844   return 0;   return 0;
# Line 1764  struct singleEntry * findEntryByPath(str Line 1962  struct singleEntry * findEntryByPath(str
1962   }   }
1963    
1964   indexVars[i + 1] = -1;   indexVars[i + 1] = -1;
1965    
1966   i = 0;   i = 0;
1967   if (index) {   if (index) {
1968      while (i < *index) i++;      while (i < *index) {
1969      if (indexVars[i] == -1) return NULL;   i++;
1970     if (indexVars[i] == -1) return NULL;
1971        }
1972   }   }
1973    
1974   entry = findEntryByIndex(config, indexVars[i]);   entry = findEntryByIndex(config, indexVars[i]);
1975   if (!entry) return NULL;   if (!entry) return NULL;
1976    
1977   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);
1978   if (!line) return NULL;   if (!line) return NULL;
1979    
1980   if (index) *index = indexVars[i];   if (index) *index = indexVars[i];
# Line 1825  struct singleEntry * findEntryByPath(str Line 2025  struct singleEntry * findEntryByPath(str
2025      for (line = entry->lines; line; line = line->next) {      for (line = entry->lines; line; line = line->next) {
2026   enum lineType_e ct = checkType;   enum lineType_e ct = checkType;
2027   if (entry->multiboot && checkType == LT_KERNEL)   if (entry->multiboot && checkType == LT_KERNEL)
2028      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER;      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER|LT_KERNEL_16;
2029   else if (checkType & LT_KERNEL)   else if (checkType & LT_KERNEL)
2030      ct = checkType | LT_KERNEL_EFI;      ct = checkType | LT_KERNEL_EFI | LT_KERNEL_16;
2031   line = getLineByType(ct, line);   line = getLineByType(ct, line);
2032   if (!line)   if (!line)
2033      break;  /* not found in this entry */      break;  /* not found in this entry */
# Line 1849  struct singleEntry * findEntryByPath(str Line 2049  struct singleEntry * findEntryByPath(str
2049       * non-Linux boot entries (could find netbsd etc, though, which is       * non-Linux boot entries (could find netbsd etc, though, which is
2050       * unfortunate)       * unfortunate)
2051       */       */
2052      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))
2053   break; /* found 'im! */   break; /* found 'im! */
2054   }   }
2055    
# Line 1859  struct singleEntry * findEntryByPath(str Line 2059  struct singleEntry * findEntryByPath(str
2059      return entry;      return entry;
2060  }  }
2061    
2062    struct singleEntry * findEntryByTitle(struct grubConfig * cfg, char *title,
2063          int * index) {
2064        struct singleEntry * entry;
2065        struct singleLine * line;
2066        int i;
2067        char * newtitle;
2068    
2069        for (i = 0, entry = cfg->entries; entry; entry = entry->next, i++) {
2070     if (index && i < *index)
2071        continue;
2072     line = getLineByType(LT_TITLE, entry->lines);
2073     if (!line)
2074        line = getLineByType(LT_MENUENTRY, entry->lines);
2075     if (!line)
2076        continue;
2077     newtitle = grub2ExtractTitle(line);
2078     if (!newtitle)
2079        continue;
2080     if (!strcmp(title, newtitle))
2081        break;
2082        }
2083    
2084        if (!entry)
2085     return NULL;
2086    
2087        if (index)
2088     *index = i;
2089        return entry;
2090    }
2091    
2092  struct singleEntry * findEntryByIndex(struct grubConfig * cfg, int index) {  struct singleEntry * findEntryByIndex(struct grubConfig * cfg, int index) {
2093      struct singleEntry * entry;      struct singleEntry * entry;
2094    
# Line 1881  struct singleEntry * findTemplate(struct Line 2111  struct singleEntry * findTemplate(struct
2111      struct singleEntry * entry, * entry2;      struct singleEntry * entry, * entry2;
2112      int index;      int index;
2113    
2114      if (cfg->defaultImage > -1) {      if (cfg->cfi->defaultIsSaved) {
2115     if (cfg->cfi->getEnv) {
2116        char *defTitle = cfg->cfi->getEnv(cfg->cfi, "saved_entry");
2117        if (defTitle) {
2118     int index = 0;
2119     if (isnumber(defTitle)) {
2120        index = atoi(defTitle);
2121        entry = findEntryByIndex(cfg, index);
2122     } else {
2123        entry = findEntryByTitle(cfg, defTitle, &index);
2124     }
2125     if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2126        cfg->defaultImage = index;
2127        if (indexPtr)
2128     *indexPtr = index;
2129        return entry;
2130     }
2131        }
2132     }
2133        } else if (cfg->defaultImage > -1) {
2134   entry = findEntryByIndex(cfg, cfg->defaultImage);   entry = findEntryByIndex(cfg, cfg->defaultImage);
2135   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2136      if (indexPtr) *indexPtr = cfg->defaultImage;      if (indexPtr) *indexPtr = cfg->defaultImage;
# Line 2035  void displayEntry(struct singleEntry * e Line 2284  void displayEntry(struct singleEntry * e
2284      struct singleLine * line;      struct singleLine * line;
2285      char * root = NULL;      char * root = NULL;
2286      int i;      int i;
2287        int j;
2288    
2289      printf("index=%d\n", index);      printf("index=%d\n", index);
2290    
2291      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);
2292      if (!line) {      if (!line) {
2293          printf("non linux entry\n");          printf("non linux entry\n");
2294          return;          return;
# Line 2103  void displayEntry(struct singleEntry * e Line 2353  void displayEntry(struct singleEntry * e
2353   printf("root=%s\n", s);   printf("root=%s\n", s);
2354      }      }
2355    
2356      line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines);      line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
2357    
2358      if (line && line->numElements >= 2) {      if (line && line->numElements >= 2) {
2359   if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))   if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
# Line 2122  void displayEntry(struct singleEntry * e Line 2372  void displayEntry(struct singleEntry * e
2372      } else {      } else {
2373   char * title;   char * title;
2374   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
2375   title = grub2ExtractTitle(line);   if (line) {
2376   if (title)      title = grub2ExtractTitle(line);
2377      printf("title=%s\n", title);      if (title)
2378     printf("title=%s\n", title);
2379     }
2380        }
2381    
2382        for (j = 0, line = entry->lines; line; line = line->next) {
2383     if ((line->type & LT_MBMODULE) && line->numElements >= 2) {
2384        if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
2385     printf("mbmodule%d=", j);
2386        else
2387     printf("mbmodule%d=%s", j, prefix);
2388    
2389        for (i = 1; i < line->numElements; i++)
2390     printf("%s%s", line->elements[i].item, line->elements[i].indent);
2391        printf("\n");
2392        j++;
2393     }
2394      }      }
2395  }  }
2396    
# Line 2520  struct singleLine * addLineTmpl(struct s Line 2786  struct singleLine * addLineTmpl(struct s
2786   insertElement(newLine, val, 1, cfi);   insertElement(newLine, val, 1, cfi);
2787    
2788   /* but try to keep the rootspec from the template... sigh */   /* but try to keep the rootspec from the template... sigh */
2789   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)) {
2790      char * rootspec = getRootSpecifier(tmplLine->elements[1].item);      char * rootspec = getRootSpecifier(tmplLine->elements[1].item);
2791      if (rootspec != NULL) {      if (rootspec != NULL) {
2792   free(newLine->elements[1].item);   free(newLine->elements[1].item);
# Line 2890  int updateActualImage(struct grubConfig Line 3156  int updateActualImage(struct grubConfig
3156      firstElement = 2;      firstElement = 2;
3157    
3158   } else {   } else {
3159      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);
3160      if (!line) {      if (!line) {
3161   /* no LT_KERNEL or LT_MBMODULE in this entry? */   /* no LT_KERNEL or LT_MBMODULE in this entry? */
3162   continue;   continue;
# Line 3046  int updateImage(struct grubConfig * cfg, Line 3312  int updateImage(struct grubConfig * cfg,
3312      return rc;      return rc;
3313  }  }
3314    
3315    int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,
3316     const char * image, const char * prefix, const char * initrd,
3317     const char * title) {
3318        struct singleEntry * entry;
3319        struct singleLine * line, * kernelLine, *endLine = NULL;
3320        int index = 0;
3321    
3322        if (!image) return 0;
3323    
3324        for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3325            kernelLine = getLineByType(LT_MBMODULE, entry->lines);
3326            if (!kernelLine) continue;
3327    
3328     /* if title is supplied, the entry's title must match it. */
3329     if (title) {
3330        char *linetitle;
3331    
3332        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3333        if (!line)
3334     continue;
3335    
3336        linetitle = extractTitle(line);
3337        if (!linetitle)
3338     continue;
3339        if (strcmp(title, linetitle)) {
3340     free(linetitle);
3341     continue;
3342        }
3343        free(linetitle);
3344     }
3345    
3346            if (prefix) {
3347                int prefixLen = strlen(prefix);
3348                if (!strncmp(initrd, prefix, prefixLen))
3349                    initrd += prefixLen;
3350            }
3351     endLine = getLineByType(LT_ENTRY_END, entry->lines);
3352     if (endLine)
3353        removeLine(entry, endLine);
3354            line = addLine(entry, cfg->cfi, preferredLineType(LT_MBMODULE,cfg->cfi),
3355     kernelLine->indent, initrd);
3356            if (!line)
3357        return 1;
3358     if (endLine) {
3359        line = addLine(entry, cfg->cfi, LT_ENTRY_END, "", NULL);
3360                if (!line)
3361     return 1;
3362     }
3363    
3364            break;
3365        }
3366    
3367        return 0;
3368    }
3369    
3370  int updateInitrd(struct grubConfig * cfg, const char * image,  int updateInitrd(struct grubConfig * cfg, const char * image,
3371                   const char * prefix, const char * initrd) {                   const char * prefix, const char * initrd, const char * title) {
3372      struct singleEntry * entry;      struct singleEntry * entry;
3373      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3374      int index = 0;      int index = 0;
# Line 3055  int updateInitrd(struct grubConfig * cfg Line 3376  int updateInitrd(struct grubConfig * cfg
3376      if (!image) return 0;      if (!image) return 0;
3377    
3378      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3379          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI, entry->lines);          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3380          if (!kernelLine) continue;          if (!kernelLine) continue;
3381    
3382          line = getLineByType(LT_INITRD|LT_INITRD_EFI, entry->lines);   /* if title is supplied, the entry's title must match it. */
3383     if (title) {
3384        char *linetitle;
3385    
3386        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3387        if (!line)
3388     continue;
3389    
3390        linetitle = extractTitle(line);
3391        if (!linetitle)
3392     continue;
3393        if (strcmp(title, linetitle)) {
3394     free(linetitle);
3395     continue;
3396        }
3397        free(linetitle);
3398     }
3399    
3400            line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
3401          if (line)          if (line)
3402              removeLine(entry, line);              removeLine(entry, line);
3403          if (prefix) {          if (prefix) {
# Line 3069  int updateInitrd(struct grubConfig * cfg Line 3408  int updateInitrd(struct grubConfig * cfg
3408   endLine = getLineByType(LT_ENTRY_END, entry->lines);   endLine = getLineByType(LT_ENTRY_END, entry->lines);
3409   if (endLine)   if (endLine)
3410      removeLine(entry, endLine);      removeLine(entry, endLine);
3411          line = addLine(entry, cfg->cfi, preferredLineType(LT_INITRD, cfg->cfi),   enum lineType_e lt;
3412   kernelLine->indent, initrd);   switch(kernelLine->type) {
3413        case LT_KERNEL:
3414            lt = LT_INITRD;
3415     break;
3416        case LT_KERNEL_EFI:
3417            lt = LT_INITRD_EFI;
3418     break;
3419        case LT_KERNEL_16:
3420            lt = LT_INITRD_16;
3421     break;
3422        default:
3423            lt = preferredLineType(LT_INITRD, cfg->cfi);
3424     }
3425            line = addLine(entry, cfg->cfi, lt, kernelLine->indent, initrd);
3426          if (!line)          if (!line)
3427      return 1;      return 1;
3428   if (endLine) {   if (endLine) {
# Line 3429  int addNewKernel(struct grubConfig * con Line 3781  int addNewKernel(struct grubConfig * con
3781   const char * newKernelPath, const char * newKernelTitle,   const char * newKernelPath, const char * newKernelTitle,
3782   const char * newKernelArgs, const char * newKernelInitrd,   const char * newKernelArgs, const char * newKernelInitrd,
3783   const char ** extraInitrds, int extraInitrdCount,   const char ** extraInitrds, int extraInitrdCount,
3784                   const char * newMBKernel, const char * newMBKernelArgs) {                   const char * newMBKernel, const char * newMBKernelArgs,
3785     const char * newDevTreePath) {
3786      struct singleEntry * new;      struct singleEntry * new;
3787      struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL;      struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL;
3788      int needs;      int needs;
# Line 3470  int addNewKernel(struct grubConfig * con Line 3823  int addNewKernel(struct grubConfig * con
3823          needs |= NEED_MB;          needs |= NEED_MB;
3824          new->multiboot = 1;          new->multiboot = 1;
3825      }      }
3826        if (newDevTreePath && getKeywordByType(LT_DEVTREE, config->cfi))
3827     needs |= NEED_DEVTREE;
3828    
3829      if (template) {      if (template) {
3830   for (masterLine = template->lines;   for (masterLine = template->lines;
# Line 3655  int addNewKernel(struct grubConfig * con Line 4010  int addNewKernel(struct grubConfig * con
4010   newLine = addLineTmpl(new, tmplLine, newLine, NULL,   newLine = addLineTmpl(new, tmplLine, newLine, NULL,
4011   config->cfi);   config->cfi);
4012      }      }
4013        } else if (tmplLine->type == LT_DEVTREE &&
4014           tmplLine->numElements == 2 && newDevTreePath) {
4015            newLine = addLineTmpl(new, tmplLine, newLine,
4016          newDevTreePath + strlen(prefix),
4017          config->cfi);
4018     needs &= ~NEED_DEVTREE;
4019        } else if (tmplLine->type == LT_ENTRY_END && needs & NEED_DEVTREE) {
4020     const char *ndtp = newDevTreePath;
4021     if (!strncmp(newDevTreePath, prefix, strlen(prefix)))
4022        ndtp += strlen(prefix);
4023     newLine = addLine(new, config->cfi, LT_DEVTREE,
4024      config->secondaryIndent,
4025      ndtp);
4026     needs &= ~NEED_DEVTREE;
4027     newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);
4028      } else {      } else {
4029   /* pass through other lines from the template */   /* pass through other lines from the template */
4030   newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);   newLine = addLineTmpl(new, tmplLine, newLine, NULL, config->cfi);
# Line 3668  int addNewKernel(struct grubConfig * con Line 4038  int addNewKernel(struct grubConfig * con
4038   switch (config->cfi->entryStart) {   switch (config->cfi->entryStart) {
4039      case LT_KERNEL:      case LT_KERNEL:
4040      case LT_KERNEL_EFI:      case LT_KERNEL_EFI:
4041        case LT_KERNEL_16:
4042   if (new->multiboot && config->cfi->mbHyperFirst) {   if (new->multiboot && config->cfi->mbHyperFirst) {
4043      /* fall through to LT_HYPER */      /* fall through to LT_HYPER */
4044   } else {   } else {
# Line 3729  int addNewKernel(struct grubConfig * con Line 4100  int addNewKernel(struct grubConfig * con
4100   }   }
4101      }      }
4102    
4103        struct singleLine *endLine = NULL;
4104        endLine = getLineByType(LT_ENTRY_END, new->lines);
4105        if (endLine) {
4106        removeLine(new, endLine);
4107        needs |= NEED_END;
4108        }
4109    
4110      /* add the remainder of the lines, i.e. those that either      /* add the remainder of the lines, i.e. those that either
4111       * 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,
4112       * all the lines following the entryStart.       * all the lines following the entryStart.
# Line 3774  int addNewKernel(struct grubConfig * con Line 4152  int addNewKernel(struct grubConfig * con
4152   free(initrdVal);   free(initrdVal);
4153   needs &= ~NEED_INITRD;   needs &= ~NEED_INITRD;
4154      }      }
4155        if (needs & NEED_DEVTREE) {
4156     newLine = addLine(new, config->cfi, LT_DEVTREE,
4157      config->secondaryIndent,
4158      newDevTreePath);
4159     needs &= ~NEED_DEVTREE;
4160        }
4161    
4162        /* NEEDS_END must be last on bootloaders that need it... */
4163      if (needs & NEED_END) {      if (needs & NEED_END) {
4164   newLine = addLine(new, config->cfi, LT_ENTRY_END,   newLine = addLine(new, config->cfi, LT_ENTRY_END,
4165   config->secondaryIndent, NULL);   config->secondaryIndent, NULL);
# Line 3825  int main(int argc, const char ** argv) { Line 4211  int main(int argc, const char ** argv) {
4211      char * newKernelArgs = NULL;      char * newKernelArgs = NULL;
4212      char * newKernelInitrd = NULL;      char * newKernelInitrd = NULL;
4213      char * newKernelTitle = NULL;      char * newKernelTitle = NULL;
4214      char * newKernelVersion = NULL;      char * newDevTreePath = NULL;
4215      char * newMBKernel = NULL;      char * newMBKernel = NULL;
4216      char * newMBKernelArgs = NULL;      char * newMBKernelArgs = NULL;
4217      char * removeMBKernelArgs = NULL;      char * removeMBKernelArgs = NULL;
# Line 3835  int main(int argc, const char ** argv) { Line 4221  int main(int argc, const char ** argv) {
4221      char * removeArgs = NULL;      char * removeArgs = NULL;
4222      char * kernelInfo = NULL;      char * kernelInfo = NULL;
4223      char * extraInitrds[MAX_EXTRA_INITRDS] = { NULL };      char * extraInitrds[MAX_EXTRA_INITRDS] = { NULL };
4224        char * envPath = NULL;
4225      const char * chptr = NULL;      const char * chptr = NULL;
4226      struct configFileInfo * cfi = NULL;      struct configFileInfo * cfi = NULL;
4227      struct grubConfig * config;      struct grubConfig * config;
# Line 3882  int main(int argc, const char ** argv) { Line 4269  int main(int argc, const char ** argv) {
4269      _("display the index of the default kernel") },      _("display the index of the default kernel") },
4270   { "default-title", 0, 0, &displayDefaultTitle, 0,   { "default-title", 0, 0, &displayDefaultTitle, 0,
4271      _("display the title of the default kernel") },      _("display the title of the default kernel") },
4272     { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4273        _("device tree file for new stanza"), _("dtb-path") },
4274     { "devtreedir", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4275        _("device tree directory for new stanza"), _("dtb-path") },
4276   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,
4277      _("configure elilo bootloader") },      _("configure elilo bootloader") },
4278   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,
4279      _("force grub2 stanzas to use efi") },      _("force grub2 stanzas to use efi") },
4280     { "env", 0, POPT_ARG_STRING, &envPath, 0,
4281        _("path for environment data"),
4282        _("path") },
4283   { "extlinux", 0, POPT_ARG_NONE, &configureExtLinux, 0,   { "extlinux", 0, POPT_ARG_NONE, &configureExtLinux, 0,
4284      _("configure extlinux bootloader (from syslinux)") },      _("configure extlinux bootloader (from syslinux)") },
4285   { "grub", 0, POPT_ARG_NONE, &configureGrub, 0,   { "grub", 0, POPT_ARG_NONE, &configureGrub, 0,
# Line 3999  int main(int argc, const char ** argv) { Line 4393  int main(int argc, const char ** argv) {
4393   return 1;   return 1;
4394      } else if (configureGrub2) {      } else if (configureGrub2) {
4395   cfi = &grub2ConfigType;   cfi = &grub2ConfigType;
4396     if (envPath)
4397        cfi->envFile = envPath;
4398      } else if (configureLilo) {      } else if (configureLilo) {
4399   cfi = &liloConfigType;   cfi = &liloConfigType;
4400      } else if (configureGrub) {      } else if (configureGrub) {
# Line 4042  int main(int argc, const char ** argv) { Line 4438  int main(int argc, const char ** argv) {
4438      grubConfig = cfi->defaultConfig;      grubConfig = cfi->defaultConfig;
4439      }      }
4440    
4441      if (bootloaderProbe && (displayDefault || kernelInfo || newKernelVersion ||      if (bootloaderProbe && (displayDefault || kernelInfo ||
4442      newKernelPath || removeKernelPath || makeDefault ||      newKernelPath || removeKernelPath || makeDefault ||
4443      defaultKernel || displayDefaultIndex || displayDefaultTitle ||      defaultKernel || displayDefaultIndex || displayDefaultTitle ||
4444      (defaultIndex >= 0))) {      (defaultIndex >= 0))) {
# Line 4051  int main(int argc, const char ** argv) { Line 4447  int main(int argc, const char ** argv) {
4447   return 1;   return 1;
4448      }      }
4449    
4450      if ((displayDefault || kernelInfo) && (newKernelVersion || newKernelPath ||      if ((displayDefault || kernelInfo) && (newKernelPath ||
4451     removeKernelPath)) {     removeKernelPath)) {
4452   fprintf(stderr, _("grubby: --default-kernel and --info may not "   fprintf(stderr, _("grubby: --default-kernel and --info may not "
4453    "be used when adding or removing kernels\n"));    "be used when adding or removing kernels\n"));
# Line 4061  int main(int argc, const char ** argv) { Line 4457  int main(int argc, const char ** argv) {
4457      if (newKernelPath && !newKernelTitle) {      if (newKernelPath && !newKernelTitle) {
4458   fprintf(stderr, _("grubby: kernel title must be specified\n"));   fprintf(stderr, _("grubby: kernel title must be specified\n"));
4459   return 1;   return 1;
4460      } else if (!newKernelPath && (newKernelTitle  || copyDefault ||      } else if (!newKernelPath && (copyDefault ||
4461    (newKernelInitrd && !updateKernelPath)||    (newKernelInitrd && !updateKernelPath)||
4462    makeDefault || extraInitrdCount > 0)) {    makeDefault || extraInitrdCount > 0)) {
4463   fprintf(stderr, _("grubby: kernel path expected\n"));   fprintf(stderr, _("grubby: kernel path expected\n"));
# Line 4213  int main(int argc, const char ** argv) { Line 4609  int main(int argc, const char ** argv) {
4609          char * rootspec;          char * rootspec;
4610    
4611   if (config->defaultImage == -1) return 0;   if (config->defaultImage == -1) return 0;
4612     if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
4613     cfi->defaultIsSaved)
4614        config->defaultImage = 0;
4615   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
4616   if (!entry) return 0;   if (!entry) return 0;
4617   if (!suitableImage(entry, bootPrefix, 0, flags)) return 0;   if (!suitableImage(entry, bootPrefix, 0, flags)) return 0;
4618    
4619   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);
4620   if (!line) return 0;   if (!line) return 0;
4621    
4622          rootspec = getRootSpecifier(line->elements[1].item);          rootspec = getRootSpecifier(line->elements[1].item);
# Line 4231  int main(int argc, const char ** argv) { Line 4630  int main(int argc, const char ** argv) {
4630   struct singleEntry * entry;   struct singleEntry * entry;
4631    
4632   if (config->defaultImage == -1) return 0;   if (config->defaultImage == -1) return 0;
4633     if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
4634     cfi->defaultIsSaved)
4635        config->defaultImage = 0;
4636   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
4637   if (!entry) return 0;   if (!entry) return 0;
4638    
# Line 4253  int main(int argc, const char ** argv) { Line 4655  int main(int argc, const char ** argv) {
4655    
4656      } else if (displayDefaultIndex) {      } else if (displayDefaultIndex) {
4657          if (config->defaultImage == -1) return 0;          if (config->defaultImage == -1) return 0;
4658     if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
4659     cfi->defaultIsSaved)
4660        config->defaultImage = 0;
4661          printf("%i\n", config->defaultImage);          printf("%i\n", config->defaultImage);
4662            return 0;
4663    
4664      } else if (kernelInfo)      } else if (kernelInfo)
4665   return displayInfo(config, kernelInfo, bootPrefix);   return displayInfo(config, kernelInfo, bootPrefix);
# Line 4271  int main(int argc, const char ** argv) { Line 4677  int main(int argc, const char ** argv) {
4677      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,      if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
4678                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;                      removeArgs, newMBKernelArgs, removeMBKernelArgs)) return 1;
4679      if (updateKernelPath && newKernelInitrd) {      if (updateKernelPath && newKernelInitrd) {
4680              if (updateInitrd(config, updateKernelPath, bootPrefix,      if (newMBKernel) {
4681                               newKernelInitrd)) return 1;      if (addMBInitrd(config, newMBKernel, updateKernelPath,
4682     bootPrefix, newKernelInitrd,
4683     newKernelTitle))
4684        return 1;
4685        } else {
4686        if (updateInitrd(config, updateKernelPath, bootPrefix,
4687     newKernelInitrd, newKernelTitle))
4688     return 1;
4689        }
4690      }      }
4691      if (addNewKernel(config, template, bootPrefix, newKernelPath,      if (addNewKernel(config, template, bootPrefix, newKernelPath,
4692                       newKernelTitle, newKernelArgs, newKernelInitrd,                       newKernelTitle, newKernelArgs, newKernelInitrd,
4693                       (const char **)extraInitrds, extraInitrdCount,                       (const char **)extraInitrds, extraInitrdCount,
4694                       newMBKernel, newMBKernelArgs)) return 1;                       newMBKernel, newMBKernelArgs, newDevTreePath)) return 1;
4695            
4696    
4697      if (numEntries(config) == 0) {      if (numEntries(config) == 0) {

Legend:
Removed from v.2246  
changed lines
  Added in v.2972