Magellan Linux

Diff of /trunk/grubby/grubby.c

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

revision 2718 by niro, Wed Jul 16 11:01:36 2014 UTC revision 2991 by niro, Thu Jun 30 10:34:31 2016 UTC
# Line 222  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 451  char *grub2ExtractTitle(struct singleLin Line 452  char *grub2ExtractTitle(struct singleLin
452       * whose last character is also quote (assuming it's the closing one) */       * whose last character is also quote (assuming it's the closing one) */
453      int resultMaxSize;      int resultMaxSize;
454      char * result;      char * result;
455        /* need to ensure that ' does not match " as we search */
456        char quote_char = *current;
457            
458      resultMaxSize = sizeOfSingleLine(line);      resultMaxSize = sizeOfSingleLine(line);
459      result = malloc(resultMaxSize);      result = malloc(resultMaxSize);
# Line 464  char *grub2ExtractTitle(struct singleLin Line 467  char *grub2ExtractTitle(struct singleLin
467   current_indent_len = strlen(current_indent);   current_indent_len = strlen(current_indent);
468    
469   strncat(result, current_indent, current_indent_len);   strncat(result, current_indent, current_indent_len);
470   if (!isquote(current[current_len-1])) {   if (current[current_len-1] != quote_char) {
471      strncat(result, current, current_len);      strncat(result, current, current_len);
472   } else {   } else {
473      strncat(result, current, current_len - 1);      strncat(result, current, current_len - 1);
# Line 582  struct keywordTypes extlinuxKeywords[] = Line 585  struct keywordTypes extlinuxKeywords[] =
585      { "initrd",    LT_INITRD,      ' ', ',' },      { "initrd",    LT_INITRD,      ' ', ',' },
586      { "append",    LT_KERNELARGS,  ' ' },      { "append",    LT_KERNELARGS,  ' ' },
587      { "prompt",     LT_UNKNOWN,     ' ' },      { "prompt",     LT_UNKNOWN,     ' ' },
588        { "fdt",        LT_DEVTREE,     ' ' },
589        { "fdtdir",     LT_DEVTREE,     ' ' },
590      { NULL,    0, 0 },      { NULL,    0, 0 },
591  };  };
592  int useextlinuxmenu;  int useextlinuxmenu;
# Line 592  struct configFileInfo eliloConfigType = Line 597  struct configFileInfo eliloConfigType =
597      .needsBootPrefix = 1,      .needsBootPrefix = 1,
598      .argsInQuotes = 1,      .argsInQuotes = 1,
599      .mbConcatArgs = 1,      .mbConcatArgs = 1,
600        .titlePosition = 1,
601  };  };
602    
603  struct configFileInfo liloConfigType = {  struct configFileInfo liloConfigType = {
# Line 600  struct configFileInfo liloConfigType = { Line 606  struct configFileInfo liloConfigType = {
606      .entryStart = LT_KERNEL,      .entryStart = LT_KERNEL,
607      .argsInQuotes = 1,      .argsInQuotes = 1,
608      .maxTitleLength = 15,      .maxTitleLength = 15,
609        .titlePosition = 1,
610  };  };
611    
612  struct configFileInfo yabootConfigType = {  struct configFileInfo yabootConfigType = {
# Line 610  struct configFileInfo yabootConfigType = Line 617  struct configFileInfo yabootConfigType =
617      .argsInQuotes = 1,      .argsInQuotes = 1,
618      .maxTitleLength = 15,      .maxTitleLength = 15,
619      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
620        .titlePosition = 1,
621  };  };
622    
623  struct configFileInfo siloConfigType = {  struct configFileInfo siloConfigType = {
# Line 619  struct configFileInfo siloConfigType = { Line 627  struct configFileInfo siloConfigType = {
627      .needsBootPrefix = 1,      .needsBootPrefix = 1,
628      .argsInQuotes = 1,      .argsInQuotes = 1,
629      .maxTitleLength = 15,      .maxTitleLength = 15,
630        .titlePosition = 1,
631  };  };
632    
633  struct configFileInfo ziplConfigType = {  struct configFileInfo ziplConfigType = {
# Line 638  struct configFileInfo extlinuxConfigType Line 647  struct configFileInfo extlinuxConfigType
647      .maxTitleLength = 255,      .maxTitleLength = 255,
648      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
649      .defaultIsUnquoted = 1,      .defaultIsUnquoted = 1,
650        .titlePosition = 1,
651  };  };
652    
653  struct grubConfig {  struct grubConfig {
# Line 826  static int isEntryStart(struct singleLin Line 836  static int isEntryStart(struct singleLin
836  }  }
837    
838  /* extract the title from within brackets (for zipl) */  /* extract the title from within brackets (for zipl) */
839  static char * extractTitle(struct singleLine * line) {  static char * extractTitle(struct grubConfig *cfg, struct singleLine * line) {
840      /* bracketed title... let's extract it (leaks a byte) */      /* bracketed title... let's extract it */
841      char * title = NULL;      char * title = NULL;
842      if (line->type == LT_TITLE) {      if (line->type == LT_TITLE) {
843   title = strdup(line->elements[0].item);   char *tmp = line->elements[cfg->cfi->titlePosition].item;
844   title++;   if (cfg->cfi->titleBracketed) {
845   *(title + strlen(title) - 1) = '\0';      tmp++;
846        title = strdup(tmp);
847        *(title + strlen(title) - 1) = '\0';
848     } else {
849        title = strdup(tmp);
850     }
851      } else if (line->type == LT_MENUENTRY)      } else if (line->type == LT_MENUENTRY)
852   title = strdup(line->elements[1].item);   title = strdup(line->elements[1].item);
853      else      else
# Line 916  static int lineWrite(FILE * out, struct Line 931  static int lineWrite(FILE * out, struct
931   /* Need to handle this, because we strip the quotes from   /* Need to handle this, because we strip the quotes from
932   * menuentry when read it. */   * menuentry when read it. */
933   if (line->type == LT_MENUENTRY && i == 1) {   if (line->type == LT_MENUENTRY && i == 1) {
934      if(!isquote(*line->elements[i].item))      if(!isquote(*line->elements[i].item)) {
935   fprintf(out, "\'%s\'", line->elements[i].item);   int substring = 0;
936      else   /* If the line contains nested quotes, we did not strip
937     * the "interna" quotes and we must use the right quotes
938     * again when writing the updated file. */
939     for (int j = i; j < line->numElements; j++) {
940        if (strchr(line->elements[i].item, '\'') != NULL) {
941           substring = 1;
942           fprintf(out, "\"%s\"", line->elements[i].item);
943           break;
944        }
945     }
946     if (!substring)
947        fprintf(out, "\'%s\'", line->elements[i].item);
948        } else {
949   fprintf(out, "%s", line->elements[i].item);   fprintf(out, "%s", line->elements[i].item);
950        }
951      fprintf(out, "%s", line->elements[i].indent);      fprintf(out, "%s", line->elements[i].indent);
952    
953      continue;      continue;
# Line 1255  static struct grubConfig * readConfig(co Line 1283  static struct grubConfig * readConfig(co
1283      len = 0;      len = 0;
1284      char *extras;      char *extras;
1285      char *title;      char *title;
1286        /* initially unseen value */
1287        char quote_char = '\0';
1288    
1289      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1290   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1271  static struct grubConfig * readConfig(co Line 1301  static struct grubConfig * readConfig(co
1301      for (int i = 0; i < line->numElements; i++) {      for (int i = 0; i < line->numElements; i++) {
1302   if (!strcmp(line->elements[i].item, "menuentry"))   if (!strcmp(line->elements[i].item, "menuentry"))
1303      continue;      continue;
1304   if (isquote(*line->elements[i].item))   if (isquote(*line->elements[i].item) && quote_char == '\0') {
1305        /* ensure we properly pair off quotes */
1306        quote_char = *line->elements[i].item;
1307      title = line->elements[i].item + 1;      title = line->elements[i].item + 1;
1308   else   } else {
1309      title = line->elements[i].item;      title = line->elements[i].item;
1310     }
1311    
1312   len = strlen(title);   len = strlen(title);
1313          if (isquote(title[len-1])) {          if (title[len-1] == quote_char) {
1314      strncat(buf, title,len-1);      strncat(buf, title,len-1);
1315      break;      break;
1316   } else {   } else {
# Line 1288  static struct grubConfig * readConfig(co Line 1321  static struct grubConfig * readConfig(co
1321    
1322      /* get extras */      /* get extras */
1323      int count = 0;      int count = 0;
1324        quote_char = '\0';
1325      for (int i = 0; i < line->numElements; i++) {      for (int i = 0; i < line->numElements; i++) {
1326   if (count >= 2) {   if (count >= 2) {
1327      strcat(extras, line->elements[i].item);      strcat(extras, line->elements[i].item);
# Line 1298  static struct grubConfig * readConfig(co Line 1332  static struct grubConfig * readConfig(co
1332      continue;      continue;
1333    
1334   /* count ' or ", there should be two in menuentry line. */   /* count ' or ", there should be two in menuentry line. */
1335   if (isquote(*line->elements[i].item))   if (isquote(*line->elements[i].item) && quote_char == '\0') {
1336        /* ensure we properly pair off quotes */
1337                quote_char = *line->elements[i].item;
1338      count++;      count++;
1339     }
1340    
1341   len = strlen(line->elements[i].item);   len = strlen(line->elements[i].item);
1342    
1343   if (isquote(line->elements[i].item[len -1]))   if (line->elements[i].item[len -1] == quote_char)
1344      count++;      count++;
1345    
1346   /* ok, we get the final ' or ", others are extras. */   /* ok, we get the final ' or ", others are extras. */
# Line 1440  static struct grubConfig * readConfig(co Line 1477  static struct grubConfig * readConfig(co
1477                                  line->elements[1].item)) break;                                  line->elements[1].item)) break;
1478                  } else if (line) {                  } else if (line) {
1479                      if (!strcmp(defaultLine->elements[1].item,                      if (!strcmp(defaultLine->elements[1].item,
1480                                  extractTitle(line))) break;                                  extractTitle(cfg, line))) break;
1481                  }                  }
1482   i++;   i++;
1483   entry = NULL;   entry = NULL;
# Line 1491  static void writeDefault(FILE * out, cha Line 1528  static void writeDefault(FILE * out, cha
1528      if (!line)      if (!line)
1529   line = getLineByType(LT_TITLE, entry->lines);   line = getLineByType(LT_TITLE, entry->lines);
1530      if (line) {      if (line) {
1531   title = extractTitle(line);   title = extractTitle(cfg, line);
1532   if (title)   if (title)
1533      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);
1534      }      }
# Line 1529  static void writeDefault(FILE * out, cha Line 1566  static void writeDefault(FILE * out, cha
1566              else if (line && (line->numElements == 1) &&              else if (line && (line->numElements == 1) &&
1567                       cfg->cfi->titleBracketed) {                       cfg->cfi->titleBracketed) {
1568   fprintf(out, "%sdefault%s%s\n", indent, separator,   fprintf(out, "%sdefault%s%s\n", indent, separator,
1569                          extractTitle(line));                          extractTitle(cfg, line));
1570              }              }
1571   }   }
1572      }      }
# Line 2120  struct singleEntry * findTemplate(struct Line 2157  struct singleEntry * findTemplate(struct
2157   } else {   } else {
2158      entry = findEntryByTitle(cfg, defTitle, &index);      entry = findEntryByTitle(cfg, defTitle, &index);
2159   }   }
2160   if (entry)   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2161      cfg->defaultImage = index;      cfg->defaultImage = index;
2162        if (indexPtr)
2163     *indexPtr = index;
2164        return entry;
2165     }
2166      }      }
2167   }   }
2168      } else if (cfg->defaultImage > -1) {      } else if (cfg->defaultImage > -1) {
# Line 2366  void displayEntry(struct singleEntry * e Line 2407  void displayEntry(struct singleEntry * e
2407      } else {      } else {
2408   char * title;   char * title;
2409   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
2410   title = grub2ExtractTitle(line);   if (line) {
2411   if (title)      title = grub2ExtractTitle(line);
2412      printf("title=%s\n", title);      if (title)
2413     printf("title=%s\n", title);
2414     }
2415      }      }
2416    
2417      for (j = 0, line = entry->lines; line; line = line->next) {      for (j = 0, line = entry->lines; line; line = line->next) {
# Line 3305  int updateImage(struct grubConfig * cfg, Line 3348  int updateImage(struct grubConfig * cfg,
3348  }  }
3349    
3350  int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,  int addMBInitrd(struct grubConfig * cfg, const char *newMBKernel,
3351   const char * image, const char * prefix, const char * initrd) {   const char * image, const char * prefix, const char * initrd,
3352     const char * title) {
3353      struct singleEntry * entry;      struct singleEntry * entry;
3354      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3355      int index = 0;      int index = 0;
3356    
3357      if (!image) return 0;      if (!image) return 0;
3358    
3359      for (; (entry = findEntryByPath(cfg, newMBKernel, prefix, &index)); index++) {      for (; (entry = findEntryByPath(cfg, image, prefix, &index)); index++) {
3360          kernelLine = getLineByType(LT_MBMODULE, entry->lines);          kernelLine = getLineByType(LT_MBMODULE, entry->lines);
3361          if (!kernelLine) continue;          if (!kernelLine) continue;
3362    
3363     /* if title is supplied, the entry's title must match it. */
3364     if (title) {
3365        char *linetitle;
3366    
3367        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3368        if (!line)
3369     continue;
3370    
3371        linetitle = extractTitle(cfg, line);
3372        if (!linetitle)
3373     continue;
3374        if (strcmp(title, linetitle)) {
3375     free(linetitle);
3376     continue;
3377        }
3378        free(linetitle);
3379     }
3380    
3381          if (prefix) {          if (prefix) {
3382              int prefixLen = strlen(prefix);              int prefixLen = strlen(prefix);
3383              if (!strncmp(initrd, prefix, prefixLen))              if (!strncmp(initrd, prefix, prefixLen))
# Line 3341  int addMBInitrd(struct grubConfig * cfg, Line 3403  int addMBInitrd(struct grubConfig * cfg,
3403  }  }
3404    
3405  int updateInitrd(struct grubConfig * cfg, const char * image,  int updateInitrd(struct grubConfig * cfg, const char * image,
3406                   const char * prefix, const char * initrd) {                   const char * prefix, const char * initrd, const char * title) {
3407      struct singleEntry * entry;      struct singleEntry * entry;
3408      struct singleLine * line, * kernelLine, *endLine = NULL;      struct singleLine * line, * kernelLine, *endLine = NULL;
3409      int index = 0;      int index = 0;
# Line 3352  int updateInitrd(struct grubConfig * cfg Line 3414  int updateInitrd(struct grubConfig * cfg
3414          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);          kernelLine = getLineByType(LT_KERNEL|LT_KERNEL_EFI|LT_KERNEL_16, entry->lines);
3415          if (!kernelLine) continue;          if (!kernelLine) continue;
3416    
3417     /* if title is supplied, the entry's title must match it. */
3418     if (title) {
3419        char *linetitle;
3420    
3421        line = getLineByType(LT_TITLE|LT_MENUENTRY, entry->lines);
3422        if (!line)
3423     continue;
3424    
3425        linetitle = extractTitle(cfg, line);
3426        if (!linetitle)
3427     continue;
3428        if (strcmp(title, linetitle)) {
3429     free(linetitle);
3430     continue;
3431        }
3432        free(linetitle);
3433     }
3434    
3435          line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);          line = getLineByType(LT_INITRD|LT_INITRD_EFI|LT_INITRD_16, entry->lines);
3436          if (line)          if (line)
3437              removeLine(entry, line);              removeLine(entry, line);
# Line 4132  int addNewKernel(struct grubConfig * con Line 4212  int addNewKernel(struct grubConfig * con
4212      return 0;      return 0;
4213  }  }
4214    
 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);  
 }  
   
4215  int main(int argc, const char ** argv) {  int main(int argc, const char ** argv) {
4216      poptContext optCon;      poptContext optCon;
4217      const char * grubConfig = NULL;      const char * grubConfig = NULL;
# Line 4226  int main(int argc, const char ** argv) { Line 4291  int main(int argc, const char ** argv) {
4291      _("display the title of the default kernel") },      _("display the title of the default kernel") },
4292   { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,   { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4293      _("device tree file for new stanza"), _("dtb-path") },      _("device tree file for new stanza"), _("dtb-path") },
4294     { "devtreedir", 0, POPT_ARG_STRING, &newDevTreePath, 0,
4295        _("device tree directory for new stanza"), _("dtb-path") },
4296   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,   { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0,
4297      _("configure elilo bootloader") },      _("configure elilo bootloader") },
4298   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,   { "efi", 0, POPT_ARG_NONE, &isEfi, 0,
# Line 4287  int main(int argc, const char ** argv) { Line 4354  int main(int argc, const char ** argv) {
4354    
4355      useextlinuxmenu=0;      useextlinuxmenu=0;
4356    
     signal(SIGSEGV, traceback);  
   
4357      int i = 0;      int i = 0;
4358      for (int j = 1; j < argc; j++)      for (int j = 1; j < argc; j++)
4359   i += strlen(argv[j]) + 1;   i += strlen(argv[j]) + 1;
# Line 4366  int main(int argc, const char ** argv) { Line 4431  int main(int argc, const char ** argv) {
4431      }      }
4432    
4433      if (!cfi) {      if (!cfi) {
4434          if (grub2FindConfig(&grub2ConfigType))          if (grub2FindConfig(&grub2ConfigType)) {
4435      cfi = &grub2ConfigType;      cfi = &grub2ConfigType;
4436   else      if (envPath)
4437     cfi->envFile = envPath;
4438            } else
4439        #ifdef __ia64__        #ifdef __ia64__
4440      cfi = &eliloConfigType;      cfi = &eliloConfigType;
4441        #elif __powerpc__        #elif __powerpc__
# Line 4410  int main(int argc, const char ** argv) { Line 4477  int main(int argc, const char ** argv) {
4477      if (newKernelPath && !newKernelTitle) {      if (newKernelPath && !newKernelTitle) {
4478   fprintf(stderr, _("grubby: kernel title must be specified\n"));   fprintf(stderr, _("grubby: kernel title must be specified\n"));
4479   return 1;   return 1;
4480      } else if (!newKernelPath && (newKernelTitle  || copyDefault ||      } else if (!newKernelPath && (copyDefault ||
4481    (newKernelInitrd && !updateKernelPath)||    (newKernelInitrd && !updateKernelPath)||
4482    makeDefault || extraInitrdCount > 0)) {    makeDefault || extraInitrdCount > 0)) {
4483   fprintf(stderr, _("grubby: kernel path expected\n"));   fprintf(stderr, _("grubby: kernel path expected\n"));
# Line 4632  int main(int argc, const char ** argv) { Line 4699  int main(int argc, const char ** argv) {
4699      if (updateKernelPath && newKernelInitrd) {      if (updateKernelPath && newKernelInitrd) {
4700      if (newMBKernel) {      if (newMBKernel) {
4701      if (addMBInitrd(config, newMBKernel, updateKernelPath,      if (addMBInitrd(config, newMBKernel, updateKernelPath,
4702   bootPrefix, newKernelInitrd))   bootPrefix, newKernelInitrd,
4703     newKernelTitle))
4704      return 1;      return 1;
4705      } else {      } else {
4706      if (updateInitrd(config, updateKernelPath, bootPrefix,      if (updateInitrd(config, updateKernelPath, bootPrefix,
4707   newKernelInitrd))   newKernelInitrd, newKernelTitle))
4708   return 1;   return 1;
4709      }      }
4710      }      }

Legend:
Removed from v.2718  
changed lines
  Added in v.2991