Magellan Linux

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

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

revision 2688 by niro, Wed Jul 16 10:42:34 2014 UTC revision 2995 by niro, Thu Jun 30 10:37:52 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(__arch64__)  #if defined(__aarch64__)
64  #define isEfiOnly 1  #define isEfiOnly 1
65  #else  #else
66  #define isEfiOnly 0  #define isEfiOnly 0
# Line 161  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 221  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 427  char *grub2ExtractTitle(struct singleLin Line 429  char *grub2ExtractTitle(struct singleLin
429    
430      /* bail out if line does not start with menuentry */      /* bail out if line does not start with menuentry */
431      if (strcmp(line->elements[0].item, "menuentry"))      if (strcmp(line->elements[0].item, "menuentry"))
432        return NULL;   return NULL;
433    
434      i = 1;      i = 1;
435      current = line->elements[i].item;      current = line->elements[i].item;
# Line 436  char *grub2ExtractTitle(struct singleLin Line 438  char *grub2ExtractTitle(struct singleLin
438      /* if second word is quoted, strip the quotes and return single word */      /* if second word is quoted, strip the quotes and return single word */
439      if (isquote(*current) && isquote(current[current_len - 1])) {      if (isquote(*current) && isquote(current[current_len - 1])) {
440   char *tmp;   char *tmp;
441    
442   tmp = strdup(current);   tmp = strdup(current+1);
443   *(tmp + current_len - 1) = '\0';   if (!tmp)
444   return ++tmp;      return NULL;
445     tmp[strlen(tmp)-1] = '\0';
446     return tmp;
447      }      }
448    
449      /* if no quotes, return second word verbatim */      /* if no quotes, return second word verbatim */
# Line 450  char *grub2ExtractTitle(struct singleLin Line 454  char *grub2ExtractTitle(struct singleLin
454       * whose last character is also quote (assuming it's the closing one) */       * whose last character is also quote (assuming it's the closing one) */
455      int resultMaxSize;      int resultMaxSize;
456      char * result;      char * result;
457            /* need to ensure that ' does not match " as we search */
458        char quote_char = *current;
459    
460      resultMaxSize = sizeOfSingleLine(line);      resultMaxSize = sizeOfSingleLine(line);
461      result = malloc(resultMaxSize);      result = malloc(resultMaxSize);
462      snprintf(result, resultMaxSize, "%s", ++current);      snprintf(result, resultMaxSize, "%s", ++current);
463        
464      i++;      i++;
465      for (; i < line->numElements; ++i) {      for (; i < line->numElements; ++i) {
466   current = line->elements[i].item;   current = line->elements[i].item;
# Line 463  char *grub2ExtractTitle(struct singleLin Line 469  char *grub2ExtractTitle(struct singleLin
469   current_indent_len = strlen(current_indent);   current_indent_len = strlen(current_indent);
470    
471   strncat(result, current_indent, current_indent_len);   strncat(result, current_indent, current_indent_len);
472   if (!isquote(current[current_len-1])) {   if (current[current_len-1] != quote_char) {
473      strncat(result, current, current_len);      strncat(result, current, current_len);
474   } else {   } else {
475      strncat(result, current, current_len - 1);      strncat(result, current, current_len - 1);
# Line 581  struct keywordTypes extlinuxKeywords[] = Line 587  struct keywordTypes extlinuxKeywords[] =
587      { "initrd",    LT_INITRD,      ' ', ',' },      { "initrd",    LT_INITRD,      ' ', ',' },
588      { "append",    LT_KERNELARGS,  ' ' },      { "append",    LT_KERNELARGS,  ' ' },
589      { "prompt",     LT_UNKNOWN,     ' ' },      { "prompt",     LT_UNKNOWN,     ' ' },
590        { "fdt",        LT_DEVTREE,     ' ' },
591        { "fdtdir",     LT_DEVTREE,     ' ' },
592      { NULL,    0, 0 },      { NULL,    0, 0 },
593  };  };
594  int useextlinuxmenu;  int useextlinuxmenu;
# Line 591  struct configFileInfo eliloConfigType = Line 599  struct configFileInfo eliloConfigType =
599      .needsBootPrefix = 1,      .needsBootPrefix = 1,
600      .argsInQuotes = 1,      .argsInQuotes = 1,
601      .mbConcatArgs = 1,      .mbConcatArgs = 1,
602        .titlePosition = 1,
603  };  };
604    
605  struct configFileInfo liloConfigType = {  struct configFileInfo liloConfigType = {
# Line 599  struct configFileInfo liloConfigType = { Line 608  struct configFileInfo liloConfigType = {
608      .entryStart = LT_KERNEL,      .entryStart = LT_KERNEL,
609      .argsInQuotes = 1,      .argsInQuotes = 1,
610      .maxTitleLength = 15,      .maxTitleLength = 15,
611        .titlePosition = 1,
612  };  };
613    
614  struct configFileInfo yabootConfigType = {  struct configFileInfo yabootConfigType = {
# Line 609  struct configFileInfo yabootConfigType = Line 619  struct configFileInfo yabootConfigType =
619      .argsInQuotes = 1,      .argsInQuotes = 1,
620      .maxTitleLength = 15,      .maxTitleLength = 15,
621      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
622        .titlePosition = 1,
623  };  };
624    
625  struct configFileInfo siloConfigType = {  struct configFileInfo siloConfigType = {
# Line 618  struct configFileInfo siloConfigType = { Line 629  struct configFileInfo siloConfigType = {
629      .needsBootPrefix = 1,      .needsBootPrefix = 1,
630      .argsInQuotes = 1,      .argsInQuotes = 1,
631      .maxTitleLength = 15,      .maxTitleLength = 15,
632        .titlePosition = 1,
633  };  };
634    
635  struct configFileInfo ziplConfigType = {  struct configFileInfo ziplConfigType = {
# Line 636  struct configFileInfo extlinuxConfigType Line 648  struct configFileInfo extlinuxConfigType
648      .needsBootPrefix = 1,      .needsBootPrefix = 1,
649      .maxTitleLength = 255,      .maxTitleLength = 255,
650      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
651        .defaultIsUnquoted = 1,
652        .titlePosition = 1,
653  };  };
654    
655  struct grubConfig {  struct grubConfig {
# Line 824  static int isEntryStart(struct singleLin Line 838  static int isEntryStart(struct singleLin
838  }  }
839    
840  /* extract the title from within brackets (for zipl) */  /* extract the title from within brackets (for zipl) */
841  static char * extractTitle(struct singleLine * line) {  static char * extractTitle(struct grubConfig *cfg, struct singleLine * line) {
842      /* bracketed title... let's extract it (leaks a byte) */      /* bracketed title... let's extract it */
843      char * title = NULL;      char * title = NULL;
844      if (line->type == LT_TITLE) {      if (line->type == LT_TITLE) {
845   title = strdup(line->elements[0].item);   char *tmp = line->elements[cfg->cfi->titlePosition].item;
846   title++;   if (cfg->cfi->titleBracketed) {
847   *(title + strlen(title) - 1) = '\0';      tmp++;
848        title = strdup(tmp);
849        *(title + strlen(title) - 1) = '\0';
850     } else {
851        title = strdup(tmp);
852     }
853      } else if (line->type == LT_MENUENTRY)      } else if (line->type == LT_MENUENTRY)
854   title = strdup(line->elements[1].item);   title = strdup(line->elements[1].item);
855      else      else
# Line 914  static int lineWrite(FILE * out, struct Line 933  static int lineWrite(FILE * out, struct
933   /* Need to handle this, because we strip the quotes from   /* Need to handle this, because we strip the quotes from
934   * menuentry when read it. */   * menuentry when read it. */
935   if (line->type == LT_MENUENTRY && i == 1) {   if (line->type == LT_MENUENTRY && i == 1) {
936      if(!isquote(*line->elements[i].item))      if(!isquote(*line->elements[i].item)) {
937   fprintf(out, "\'%s\'", line->elements[i].item);   int substring = 0;
938      else   /* If the line contains nested quotes, we did not strip
939     * the "interna" quotes and we must use the right quotes
940     * again when writing the updated file. */
941     for (int j = i; j < line->numElements; j++) {
942        if (strchr(line->elements[i].item, '\'') != NULL) {
943           substring = 1;
944           fprintf(out, "\"%s\"", line->elements[i].item);
945           break;
946        }
947     }
948     if (!substring)
949        fprintf(out, "\'%s\'", line->elements[i].item);
950        } else {
951   fprintf(out, "%s", line->elements[i].item);   fprintf(out, "%s", line->elements[i].item);
952        }
953      fprintf(out, "%s", line->elements[i].indent);      fprintf(out, "%s", line->elements[i].indent);
954    
955      continue;      continue;
# Line 1191  static struct grubConfig * readConfig(co Line 1223  static struct grubConfig * readConfig(co
1223   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;   cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1224   defaultLine = line;   defaultLine = line;
1225      }      }
  } else if (line->type == LT_DEFAULT && line->numElements == 2) {  
     cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;  
     defaultLine = line;  
1226    
1227          } else if (iskernel(line->type)) {          } else if (iskernel(line->type)) {
1228      /* if by some freak chance this is multiboot and the "module"      /* if by some freak chance this is multiboot and the "module"
1229       * lines came earlier in the template, make sure to use LT_HYPER       * lines came earlier in the template, make sure to use LT_HYPER
1230       * instead of LT_KERNEL now       * instead of LT_KERNEL now
1231       */       */
1232      if (entry->multiboot)      if (entry && entry->multiboot)
1233   line->type = LT_HYPER;   line->type = LT_HYPER;
1234    
1235          } else if (line->type == LT_MBMODULE) {          } else if (line->type == LT_MBMODULE) {
# Line 1226  static struct grubConfig * readConfig(co Line 1255  static struct grubConfig * readConfig(co
1255      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);      cfg->fallbackImage = strtol(line->elements[1].item, &end, 10);
1256      if (*end) cfg->fallbackImage = -1;      if (*end) cfg->fallbackImage = -1;
1257    
1258   } else if (line->type == LT_TITLE && line->numElements > 1) {   } else if ((line->type == LT_DEFAULT && cfi->defaultIsUnquoted) ||
1259      /* make the title a single argument (undoing our parsing) */                  (line->type == LT_TITLE && line->numElements > 1)) {
1260        /* make the title/default a single argument (undoing our parsing) */
1261      len = 0;      len = 0;
1262      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1263   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1255  static struct grubConfig * readConfig(co Line 1285  static struct grubConfig * readConfig(co
1285      len = 0;      len = 0;
1286      char *extras;      char *extras;
1287      char *title;      char *title;
1288        /* initially unseen value */
1289        char quote_char = '\0';
1290    
1291      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1292   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1271  static struct grubConfig * readConfig(co Line 1303  static struct grubConfig * readConfig(co
1303      for (int i = 0; i < line->numElements; i++) {      for (int i = 0; i < line->numElements; i++) {
1304   if (!strcmp(line->elements[i].item, "menuentry"))   if (!strcmp(line->elements[i].item, "menuentry"))
1305      continue;      continue;
1306   if (isquote(*line->elements[i].item))   if (isquote(*line->elements[i].item) && quote_char == '\0') {
1307        /* ensure we properly pair off quotes */
1308        quote_char = *line->elements[i].item;
1309      title = line->elements[i].item + 1;      title = line->elements[i].item + 1;
1310   else   } else {
1311      title = line->elements[i].item;      title = line->elements[i].item;
1312     }
1313    
1314   len = strlen(title);   len = strlen(title);
1315          if (isquote(title[len-1])) {          if (title[len-1] == quote_char) {
1316      strncat(buf, title,len-1);      strncat(buf, title,len-1);
1317      break;      break;
1318   } else {   } else {
# Line 1288  static struct grubConfig * readConfig(co Line 1323  static struct grubConfig * readConfig(co
1323    
1324      /* get extras */      /* get extras */
1325      int count = 0;      int count = 0;
1326        quote_char = '\0';
1327      for (int i = 0; i < line->numElements; i++) {      for (int i = 0; i < line->numElements; i++) {
1328   if (count >= 2) {   if (count >= 2) {
1329      strcat(extras, line->elements[i].item);      strcat(extras, line->elements[i].item);
# Line 1298  static struct grubConfig * readConfig(co Line 1334  static struct grubConfig * readConfig(co
1334      continue;      continue;
1335    
1336   /* count ' or ", there should be two in menuentry line. */   /* count ' or ", there should be two in menuentry line. */
1337   if (isquote(*line->elements[i].item))   if (isquote(*line->elements[i].item) && quote_char == '\0') {
1338        /* ensure we properly pair off quotes */
1339                quote_char = *line->elements[i].item;
1340      count++;      count++;
1341     }
1342    
1343   len = strlen(line->elements[i].item);   len = strlen(line->elements[i].item);
1344    
1345   if (isquote(line->elements[i].item[len -1]))   if (line->elements[i].item[len -1] == quote_char)
1346      count++;      count++;
1347    
1348   /* ok, we get the final ' or ", others are extras. */   /* ok, we get the final ' or ", others are extras. */
# Line 1334  static struct grubConfig * readConfig(co Line 1373  static struct grubConfig * readConfig(co
1373      }      }
1374   }   }
1375    
1376     if (line->type == LT_DEFAULT && line->numElements == 2) {
1377        cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT;
1378        defaultLine = line;
1379     }
1380    
1381   /* If we find a generic config option which should live at the   /* If we find a generic config option which should live at the
1382     top of the file, move it there. Old versions of grubby were     top of the file, move it there. Old versions of grubby were
1383     probably responsible for putting new images in the wrong     probably responsible for putting new images in the wrong
# Line 1435  static struct grubConfig * readConfig(co Line 1479  static struct grubConfig * readConfig(co
1479                                  line->elements[1].item)) break;                                  line->elements[1].item)) break;
1480                  } else if (line) {                  } else if (line) {
1481                      if (!strcmp(defaultLine->elements[1].item,                      if (!strcmp(defaultLine->elements[1].item,
1482                                  extractTitle(line))) break;                                  extractTitle(cfg, line))) break;
1483                  }                  }
1484   i++;   i++;
1485   entry = NULL;   entry = NULL;
# Line 1467  static struct grubConfig * readConfig(co Line 1511  static struct grubConfig * readConfig(co
1511      return cfg;      return cfg;
1512  }  }
1513    
1514  static void writeDefault(FILE * out, char * indent,  static void writeDefault(FILE * out, char * indent,
1515   char * separator, struct grubConfig * cfg) {   char * separator, struct grubConfig * cfg) {
1516      struct singleEntry * entry;      struct singleEntry * entry;
1517      struct singleLine * line;      struct singleLine * line;
1518      int i;      int i;
1519    
1520      if (!cfg->defaultImage && cfg->flags == GRUB_CONFIG_NO_DEFAULT) return;      if (!cfg->defaultImage && cfg->flags == GRUB_CONFIG_NO_DEFAULT)
1521     return;
1522    
1523      if (cfg->defaultImage == DEFAULT_SAVED)      if (cfg->defaultImage == DEFAULT_SAVED)
1524   fprintf(out, "%sdefault%ssaved\n", indent, separator);   fprintf(out, "%sdefault%ssaved\n", indent, separator);
# Line 1486  static void writeDefault(FILE * out, cha Line 1531  static void writeDefault(FILE * out, cha
1531      if (!line)      if (!line)
1532   line = getLineByType(LT_TITLE, entry->lines);   line = getLineByType(LT_TITLE, entry->lines);
1533      if (line) {      if (line) {
1534   title = extractTitle(line);   title = extractTitle(cfg, line);
1535   if (title)   if (title)
1536      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);
1537      }      }
# Line 1497  static void writeDefault(FILE * out, cha Line 1542  static void writeDefault(FILE * out, cha
1542          fprintf(out, "%sset default=\"%d\"\n", indent,          fprintf(out, "%sset default=\"%d\"\n", indent,
1543   cfg->defaultImage);   cfg->defaultImage);
1544      } else {      } else {
1545   fprintf(out, "%sdefault%s%d\n", indent, separator,   fprintf(out, "%sdefault%s%d\n", indent, separator,
1546   cfg->defaultImage);   cfg->defaultImage);
1547      }      }
1548   } else {   } else {
1549      int image = cfg->defaultImage;      int image = cfg->defaultImage;
1550    
1551      entry = cfg->entries;      entry = cfg->entries;
1552      while (entry && entry->skip) entry = entry->next;      while (entry && entry->skip)
1553     entry = entry->next;
1554    
1555      i = 0;      i = 0;
1556      while (entry && i < image) {      while (entry && i < image) {
1557   entry = entry->next;   entry = entry->next;
1558    
1559   while (entry && entry->skip) entry = entry->next;   while (entry && entry->skip)
1560        entry = entry->next;
1561   i++;   i++;
1562      }      }
1563    
1564      if (!entry) return;      if (!entry)
1565     return;
1566    
1567      line = getLineByType(LT_TITLE, entry->lines);      line = getLineByType(LT_TITLE, entry->lines);
1568    
1569      if (line && line->numElements >= 2)      if (line && line->numElements >= 2)
1570   fprintf(out, "%sdefault%s%s\n", indent, separator,   fprintf(out, "%sdefault%s%s\n", indent, separator,
1571   line->elements[1].item);   line->elements[1].item);
1572              else if (line && (line->numElements == 1) &&              else if (line && (line->numElements == 1) &&
1573                       cfg->cfi->titleBracketed) {                       cfg->cfi->titleBracketed) {
1574   fprintf(out, "%sdefault%s%s\n", indent, separator,   char *title = extractTitle(cfg, line);
1575                          extractTitle(line));   if (title) {
1576        fprintf(out, "%sdefault%s%s\n", indent, separator, title);
1577        free(title);
1578     }
1579              }              }
1580   }   }
1581      }      }
# Line 1955  struct singleEntry * findEntryByPath(str Line 2006  struct singleEntry * findEntryByPath(str
2006   }   }
2007    
2008   indexVars[i + 1] = -1;   indexVars[i + 1] = -1;
2009    
2010   i = 0;   i = 0;
2011   if (index) {   if (index) {
2012      while (i < *index) i++;      while (i < *index) {
2013      if (indexVars[i] == -1) return NULL;   i++;
2014     if (indexVars[i] == -1) return NULL;
2015        }
2016   }   }
2017    
2018   entry = findEntryByIndex(config, indexVars[i]);   entry = findEntryByIndex(config, indexVars[i]);
# Line 2113  struct singleEntry * findTemplate(struct Line 2166  struct singleEntry * findTemplate(struct
2166   } else {   } else {
2167      entry = findEntryByTitle(cfg, defTitle, &index);      entry = findEntryByTitle(cfg, defTitle, &index);
2168   }   }
2169   if (entry)   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2170      cfg->defaultImage = index;      cfg->defaultImage = index;
2171        if (indexPtr)
2172     *indexPtr = index;
2173        return entry;
2174     }
2175      }      }
2176   }   }
2177      } else if (cfg->defaultImage > -1) {      } else if (cfg->defaultImage > -1) {
# Line 2271  void displayEntry(struct singleEntry * e Line 2328  void displayEntry(struct singleEntry * e
2328      struct singleLine * line;      struct singleLine * line;
2329      char * root = NULL;      char * root = NULL;
2330      int i;      int i;
2331        int j;
2332    
2333      printf("index=%d\n", index);      printf("index=%d\n", index);
2334    
# Line 2358  void displayEntry(struct singleEntry * e Line 2416  void displayEntry(struct singleEntry * e
2416      } else {      } else {
2417   char * title;   char * title;
2418   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
2419   title = grub2ExtractTitle(line);   if (line) {
2420   if (title)      title = grub2ExtractTitle(line);
2421      printf("title=%s\n", title);      if (title)
2422     printf("title=%s\n", title);
2423     }
2424        }
2425    
2426        for (j = 0, line = entry->lines; line; line = line->next) {
2427     if ((line->type & LT_MBMODULE) && line->numElements >= 2) {
2428        if (!strncmp(prefix, line->elements[1].item, strlen(prefix)))
2429     printf("mbmodule%d=", j);
2430        else
2431     printf("mbmodule%d=%s", j, prefix);
2432    
2433        for (i = 1; i < line->numElements; i++)
2434     printf("%s%s", line->elements[i].item, line->elements[i].indent);
2435        printf("\n");
2436        j++;
2437     }
2438      }      }
2439  }  }
2440    
# Line 3283  int updateImage(struct grubConfig * cfg, Line 3357  int updateImage(struct grubConfig * cfg,
3357  }  }
3358    
3359  int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,  int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,
3360   const char * image, const char * prefix, const char * initrd) {   const char * image, const char * prefix, const char * initrd,
3361     const char * title) {
3362      struct singleEntry * entry;      struct singleEntry * entry;
3363      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3364      int index = 0;      int index = 0;
3365    
3366      if (!image) return 0;      if (!image) return 0;
3367    
3368      for (; (entry = findEntryByPath(cfg, newMBKernel, prefix, &index)); index++) {      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3369          kernelLine = getLineByType(LT_MBMODULE, entry->lines);          kernelLine = getLineByType(LT_MBMODULE, entry->lines);
3370          if (!kernelLine) continue;          if (!kernelLine) continue;
3371    
3372     /* if title is supplied, the entry's title must match it. */
3373     if (title) {
3374        char *linetitle;
3375    
3376        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3377        if (!line)
3378     continue;
3379    
3380        linetitle = extractTitle(cfg, line);
3381        if (!linetitle)
3382     continue;
3383        if (strcmp(title, linetitle)) {
3384     free(linetitle);
3385     continue;
3386        }
3387        free(linetitle);
3388     }
3389    
3390          if (prefix) {          if (prefix) {
3391              int prefixLen = strlen(prefix);              int prefixLen = strlen(prefix);
3392              if (!strncmp(initrd, prefix, prefixLen))              if (!strncmp(initrd, prefix, prefixLen))
# Line 3319  int addMBInitrd(struct grubConfig * cfg, Line 3412  int addMBInitrd(struct grubConfig * cfg,
3412  }  }
3413    
3414  int updateInitrd(struct grubConfig * cfg, const char * image,  int updateInitrd(struct grubConfig * cfg, const char * image,
3415                   const char * prefix, const char * initrd) {                   const char * prefix, const char * initrd, const char * title) {
3416      struct singleEntry * entry;      struct singleEntry * entry;
3417      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3418      int index = 0;      int index = 0;
# Line 3330  int updateInitrd(struct grubConfig * cfg Line 3423  int updateInitrd(struct grubConfig * cfg
3423          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3424          if (!kernelLine) continue;          if (!kernelLine) continue;
3425    
3426     /* if title is supplied, the entry's title must match it. */
3427     if (title) {
3428        char *linetitle;
3429    
3430        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3431        if (!line)
3432     continue;
3433    
3434        linetitle = extractTitle(cfg, line);
3435        if (!linetitle)
3436     continue;
3437        if (strcmp(title, linetitle)) {
3438     free(linetitle);
3439     continue;
3440        }
3441        free(linetitle);
3442     }
3443    
3444          line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);          line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
3445          if (line)          if (line)
3446              removeLine(entry, line);              removeLine(entry, line);
# Line 4033  int addNewKernel(struct grubConfig * con Line 4144  int addNewKernel(struct grubConfig * con
4144   }   }
4145      }      }
4146    
4147        struct singleLine *endLine = NULL;
4148        endLine = getLineByType(LT_ENTRY_END, new->lines);
4149        if (endLine) {
4150        removeLine(new, endLine);
4151        needs |= NEED_END;
4152        }
4153    
4154      /* add the remainder of the lines, i.e. those that either      /* add the remainder of the lines, i.e. those that either
4155       * 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,
4156       * all the lines following the entryStart.       * all the lines following the entryStart.
# Line 4091  int addNewKernel(struct grubConfig * con Line 4209  int addNewKernel(struct grubConfig * con
4209   config->secondaryIndent, NULL);   config->secondaryIndent, NULL);
4210   needs &= ~NEED_END;   needs &= ~NEED_END;
4211      }      }
4212    
4213      if (needs) {      if (needs) {
4214   printf(_("grubby: needs=%d, aborting\n"), needs);   printf(_("grubby: needs=%d, aborting\n"), needs);
4215   abort();   abort();
# Line 4102  int addNewKernel(struct grubConfig * con Line 4221  int addNewKernel(struct grubConfig * con
4221      return 0;      return 0;
4222  }  }
4223    
 static void traceback(int signum)  
 {  
     void *array[40];  
     size_t size;  
   
     signal(SIGSEGV, SIG_DFL);  
     memset(array, '\0', sizeof (array));  
     size = backtrace(array, 40);  
   
     fprintf(stderr, "grubby received SIGSEGV!  Backtrace (%ld):\n",  
             (unsigned long)size);  
     backtrace_symbols_fd(array, size, STDERR_FILENO);  
     exit(1);  
 }  
   
4224  int main(int argc, const char ** argv) {  int main(int argc, const char ** argv) {
4225      poptContext optCon;      poptContext optCon;
4226      const char * grubConfig = NULL;      const char * grubConfig = NULL;
# Line 4196  int main(int argc, const char ** argv) { Line 4300  int main(int argc, const char ** argv) {
4300      _("display the title of the default kernel") },      _("display the title of the default kernel") },
4301   { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,   { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4302      _("device tree file for new stanza"), _("dtb-path") },      _("device tree file for new stanza"), _("dtb-path") },
4303     { "devtreedir", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4304        _("device tree directory for new stanza"), _("dtb-path") },
4305   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,
4306      _("configure elilo bootloader") },      _("configure elilo bootloader") },
4307   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,
# Line 4257  int main(int argc, const char ** argv) { Line 4363  int main(int argc, const char ** argv) {
4363    
4364      useextlinuxmenu=0;      useextlinuxmenu=0;
4365    
     signal(SIGSEGV, traceback);  
   
4366      int i = 0;      int i = 0;
4367      for (int j = 1; j < argc; j++)      for (int j = 1; j < argc; j++)
4368   i += strlen(argv[j]) + 1;   i += strlen(argv[j]) + 1;
# Line 4336  int main(int argc, const char ** argv) { Line 4440  int main(int argc, const char ** argv) {
4440      }      }
4441    
4442      if (!cfi) {      if (!cfi) {
4443          if (grub2FindConfig(&grub2ConfigType))          if (grub2FindConfig(&grub2ConfigType)) {
4444      cfi = &grub2ConfigType;      cfi = &grub2ConfigType;
4445   else      if (envPath)
4446     cfi->envFile = envPath;
4447            } else
4448        #ifdef __ia64__        #ifdef __ia64__
4449      cfi = &eliloConfigType;      cfi = &eliloConfigType;
4450        #elif __powerpc__        #elif __powerpc__
# Line 4380  int main(int argc, const char ** argv) { Line 4486  int main(int argc, const char ** argv) {
4486      if (newKernelPath && !newKernelTitle) {      if (newKernelPath && !newKernelTitle) {
4487   fprintf(stderr, _("grubby: kernel title must be specified\n"));   fprintf(stderr, _("grubby: kernel title must be specified\n"));
4488   return 1;   return 1;
4489      } else if (!newKernelPath && (newKernelTitle  || copyDefault ||      } else if (!newKernelPath && (copyDefault ||
4490    (newKernelInitrd && !updateKernelPath)||    (newKernelInitrd && !updateKernelPath)||
4491    makeDefault || extraInitrdCount > 0)) {    makeDefault || extraInitrdCount > 0)) {
4492   fprintf(stderr, _("grubby: kernel path expected\n"));   fprintf(stderr, _("grubby: kernel path expected\n"));
# Line 4552  int main(int argc, const char ** argv) { Line 4658  int main(int argc, const char ** argv) {
4658   struct singleLine * line;   struct singleLine * line;
4659   struct singleEntry * entry;   struct singleEntry * entry;
4660    
4661   if (config->defaultImage == -1) return 0;   if (config->defaultImage == -1)
4662        return 0;
4663   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
4664   cfi->defaultIsSaved)   cfi->defaultIsSaved)
4665      config->defaultImage = 0;      config->defaultImage = 0;
4666   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
4667   if (!entry) return 0;   if (!entry)
4668     return 0;
4669    
4670   if (!configureGrub2) {   if (!configureGrub2) {
4671    line = getLineByType(LT_TITLE, entry->lines);      char *title;
4672    if (!line) return 0;      line = getLineByType(LT_TITLE, entry->lines);
4673    printf("%s\n", line->elements[1].item);      if (!line)
4674     return 0;
4675        title = extractTitle(config, line);
4676        if (!title)
4677     return 0;
4678        printf("%s\n", title);
4679        free(title);
4680   } else {   } else {
4681    char * title;      char * title;
4682    
4683    dbgPrintf("This is GRUB2, default title is embeded in menuentry\n");      dbgPrintf("This is GRUB2, default title is embeded in menuentry\n");
4684    line = getLineByType(LT_MENUENTRY, entry->lines);      line = getLineByType(LT_MENUENTRY, entry->lines);
4685    if (!line) return 0;      if (!line)
4686    title = grub2ExtractTitle(line);   return 0;
4687    if (title)      title = grub2ExtractTitle(line);
4688      printf("%s\n", title);      if (title)
4689     printf("%s\n", title);
4690   }   }
4691   return 0;   return 0;
4692    
# Line 4602  int main(int argc, const char ** argv) { Line 4716  int main(int argc, const char ** argv) {
4716      if (updateKernelPath && newKernelInitrd) {      if (updateKernelPath && newKernelInitrd) {
4717      if (newMBKernel) {      if (newMBKernel) {
4718      if (addMBInitrd(config, newMBKernel, updateKernelPath,      if (addMBInitrd(config, newMBKernel, updateKernelPath,
4719   bootPrefix, newKernelInitrd))   bootPrefix, newKernelInitrd,
4720     newKernelTitle))
4721      return 1;      return 1;
4722      } else {      } else {
4723      if (updateInitrd(config, updateKernelPath, bootPrefix,      if (updateInitrd(config, updateKernelPath, bootPrefix,
4724   newKernelInitrd))   newKernelInitrd, newKernelTitle))
4725   return 1;   return 1;
4726      }      }
4727      }      }

Legend:
Removed from v.2688  
changed lines
  Added in v.2995