Magellan Linux

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

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

revision 1940 by niro, Mon Oct 1 12:39:50 2012 UTC revision 2250 by niro, Mon Oct 21 13:56:22 2013 UTC
# Line 36  Line 36 
36  #include <signal.h>  #include <signal.h>
37  #include <blkid/blkid.h>  #include <blkid/blkid.h>
38    
39    #include "log.h"
40    
41  #ifndef DEBUG  #ifndef DEBUG
42  #define DEBUG 0  #define DEBUG 0
43  #endif  #endif
# Line 58  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    char *saved_command_line = NULL;
64    
65  /* comments get lumped in with indention */  /* comments get lumped in with indention */
66  struct lineElement {  struct lineElement {
67      char * item;      char * item;
# Line 138  struct configFileInfo { Line 142  struct configFileInfo {
142      findConfigFunc findConfig;      findConfigFunc findConfig;
143      writeLineFunc writeLine;      writeLineFunc writeLine;
144      struct keywordTypes * keywords;      struct keywordTypes * keywords;
145        int caseInsensitive;
146      int defaultIsIndex;      int defaultIsIndex;
147      int defaultIsVariable;      int defaultIsVariable;
148      int defaultSupportSaved;      int defaultSupportSaved;
# Line 225  const char *grub2FindConfig(struct confi Line 230  const char *grub2FindConfig(struct confi
230      };      };
231      static int i = -1;      static int i = -1;
232      static const char *grub_cfg = "/boot/grub/grub.cfg";      static const char *grub_cfg = "/boot/grub/grub.cfg";
233        int rc = -1;
234    
235      if (i == -1) {      if (i == -1) {
236   for (i = 0; configFiles[i] != NULL; i++) {   for (i = 0; configFiles[i] != NULL; i++) {
237      dbgPrintf("Checking \"%s\": ", configFiles[i]);      dbgPrintf("Checking \"%s\": ", configFiles[i]);
238      if (!access(configFiles[i], R_OK)) {      if ((rc = access(configFiles[i], R_OK))) {
239     if (errno == EACCES) {
240        printf("Unable to access bootloader configuration file "
241           "\"%s\": %m\n", configFiles[i]);
242        exit(1);
243     }
244     continue;
245        } else {
246   dbgPrintf("found\n");   dbgPrintf("found\n");
247   return configFiles[i];   return configFiles[i];
248      }      }
# Line 496  struct configFileInfo ziplConfigType = { Line 509  struct configFileInfo ziplConfigType = {
509  struct configFileInfo extlinuxConfigType = {  struct configFileInfo extlinuxConfigType = {
510      .defaultConfig = "/boot/extlinux/extlinux.conf",      .defaultConfig = "/boot/extlinux/extlinux.conf",
511      .keywords = extlinuxKeywords,      .keywords = extlinuxKeywords,
512        .caseInsensitive = 1,
513      .entryStart = LT_TITLE,      .entryStart = LT_TITLE,
514      .needsBootPrefix = 1,      .needsBootPrefix = 1,
515      .maxTitleLength = 255,      .maxTitleLength = 255,
# Line 632  static char * getuuidbydev(char *device) Line 646  static char * getuuidbydev(char *device)
646  static enum lineType_e getTypeByKeyword(char * keyword,  static enum lineType_e getTypeByKeyword(char * keyword,
647   struct configFileInfo * cfi) {   struct configFileInfo * cfi) {
648      for (struct keywordTypes *kw = cfi->keywords; kw->key; kw++) {      for (struct keywordTypes *kw = cfi->keywords; kw->key; kw++) {
649   if (!strcmp(keyword, kw->key))   if (cfi->caseInsensitive) {
650      return kw->type;      if (!strcasecmp(keyword, kw->key))
651                    return kw->type;
652     } else {
653        if (!strcmp(keyword, kw->key))
654            return kw->type;
655     }
656      }      }
657      return LT_UNKNOWN;      return LT_UNKNOWN;
658  }  }
# Line 947  static struct grubConfig * readConfig(co Line 966  static struct grubConfig * readConfig(co
966      int len;      int len;
967      char * buf;      char * buf;
968    
969      if (!strcmp(inName, "-")) {      if (inName == NULL) {
970            printf("Could not find bootloader configuration\n");
971            exit(1);
972        } else if (!strcmp(inName, "-")) {
973   in = 0;   in = 0;
974      } else {      } else {
975   if ((in = open(inName, O_RDONLY)) < 0) {   if ((in = open(inName, O_RDONLY)) < 0) {
# Line 1527  static char *findDiskForRoot() Line 1549  static char *findDiskForRoot()
1549      return NULL;      return NULL;
1550  }  }
1551    
1552  void printEntry(struct singleEntry * entry) {  void printEntry(struct singleEntry * entry, FILE *f) {
1553      int i;      int i;
1554      struct singleLine * line;      struct singleLine * line;
1555    
1556      for (line = entry->lines; line; line = line->next) {      for (line = entry->lines; line; line = line->next) {
1557   fprintf(stderr, "DBG: %s", line->indent);   log_message(f, "DBG: %s", line->indent);
1558   for (i = 0; i < line->numElements; i++) {   for (i = 0; i < line->numElements; i++) {
1559      /* Need to handle this, because we strip the quotes from      /* Need to handle this, because we strip the quotes from
1560       * menuentry when read it. */       * menuentry when read it. */
1561      if (line->type == LT_MENUENTRY && i == 1) {      if (line->type == LT_MENUENTRY && i == 1) {
1562   if(!isquote(*line->elements[i].item))   if(!isquote(*line->elements[i].item))
1563      fprintf(stderr, "\'%s\'", line->elements[i].item);      log_message(f, "\'%s\'", line->elements[i].item);
1564   else   else
1565      fprintf(stderr, "%s", line->elements[i].item);      log_message(f, "%s", line->elements[i].item);
1566   fprintf(stderr, "%s", line->elements[i].indent);   log_message(f, "%s", line->elements[i].indent);
1567    
1568   continue;   continue;
1569      }      }
1570            
1571      fprintf(stderr, "%s%s",      log_message(f, "%s%s",
1572      line->elements[i].item, line->elements[i].indent);      line->elements[i].item, line->elements[i].indent);
1573   }   }
1574   fprintf(stderr, "\n");   log_message(f, "\n");
1575      }      }
1576  }  }
1577    
1578  void notSuitablePrintf(struct singleEntry * entry, const char *fmt, ...)  void notSuitablePrintf(struct singleEntry * entry, int okay, const char *fmt, ...)
1579  {  {
1580      va_list argp;      static int once;
1581        va_list argp, argq;
1582    
1583        va_start(argp, fmt);
1584    
1585        va_copy(argq, argp);
1586        if (!once) {
1587     log_time(NULL);
1588     log_message(NULL, "command line: %s\n", saved_command_line);
1589        }
1590        log_message(NULL, "DBG: Image entry %s: ", okay ? "succeeded" : "failed");
1591        log_vmessage(NULL, fmt, argq);
1592    
1593        printEntry(entry, NULL);
1594        va_end(argq);
1595    
1596      if (!debug)      if (!debug) {
1597     once = 1;
1598         va_end(argp);
1599   return;   return;
1600        }
1601    
1602      va_start(argp, fmt);      if (okay) {
1603     va_end(argp);
1604     return;
1605        }
1606    
1607        if (!once)
1608     log_message(stderr, "DBG: command line: %s\n", saved_command_line);
1609        once = 1;
1610      fprintf(stderr, "DBG: Image entry failed: ");      fprintf(stderr, "DBG: Image entry failed: ");
1611      vfprintf(stderr, fmt, argp);      vfprintf(stderr, fmt, argp);
1612      printEntry(entry);      printEntry(entry, stderr);
1613      va_end(argp);      va_end(argp);
1614  }  }
1615    
# Line 1590  int suitableImage(struct singleEntry * e Line 1636  int suitableImage(struct singleEntry * e
1636      char * rootdev;      char * rootdev;
1637    
1638      if (skipRemoved && entry->skip) {      if (skipRemoved && entry->skip) {
1639   notSuitablePrintf(entry, "marked to skip\n");   notSuitablePrintf(entry, 0, "marked to skip\n");
1640   return 0;   return 0;
1641      }      }
1642    
1643      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);      line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines);
1644      if (!line) {      if (!line) {
1645   notSuitablePrintf(entry, "no line found\n");   notSuitablePrintf(entry, 0, "no line found\n");
1646   return 0;   return 0;
1647      }      }
1648      if (line->numElements < 2) {      if (line->numElements < 2) {
1649   notSuitablePrintf(entry, "line has only %d elements\n",   notSuitablePrintf(entry, 0, "line has only %d elements\n",
1650      line->numElements);      line->numElements);
1651   return 0;   return 0;
1652      }      }
1653    
1654      if (flags & GRUBBY_BADIMAGE_OKAY) return 1;      if (flags & GRUBBY_BADIMAGE_OKAY) {
1655        notSuitablePrintf(entry, 1, "\n");
1656        return 1;
1657        }
1658    
1659      fullName = alloca(strlen(bootPrefix) +      fullName = alloca(strlen(bootPrefix) +
1660        strlen(line->elements[1].item) + 1);        strlen(line->elements[1].item) + 1);
# Line 1616  int suitableImage(struct singleEntry * e Line 1665  int suitableImage(struct singleEntry * e
1665      sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/",      sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/",
1666              line->elements[1].item + rootspec_offset);              line->elements[1].item + rootspec_offset);
1667      if (access(fullName, R_OK)) {      if (access(fullName, R_OK)) {
1668   notSuitablePrintf(entry, "access to %s failed\n", fullName);   notSuitablePrintf(entry, 0, "access to %s failed\n", fullName);
1669   return 0;   return 0;
1670      }      }
1671      for (i = 2; i < line->numElements; i++)      for (i = 2; i < line->numElements; i++)
# Line 1637  int suitableImage(struct singleEntry * e Line 1686  int suitableImage(struct singleEntry * e
1686    
1687              /* failed to find one */              /* failed to find one */
1688              if (!line) {              if (!line) {
1689   notSuitablePrintf(entry, "no line found\n");   notSuitablePrintf(entry, 0, "no line found\n");
1690   return 0;   return 0;
1691              }              }
1692    
# Line 1646  int suitableImage(struct singleEntry * e Line 1695  int suitableImage(struct singleEntry * e
1695      if (i < line->numElements)      if (i < line->numElements)
1696          dev = line->elements[i].item + 5;          dev = line->elements[i].item + 5;
1697      else {      else {
1698   notSuitablePrintf(entry, "no root= entry found\n");   notSuitablePrintf(entry, 0, "no root= entry found\n");
1699   /* it failed too...  can't find root= */   /* it failed too...  can't find root= */
1700          return 0;          return 0;
1701              }              }
# Line 1655  int suitableImage(struct singleEntry * e Line 1704  int suitableImage(struct singleEntry * e
1704    
1705      dev = getpathbyspec(dev);      dev = getpathbyspec(dev);
1706      if (!getpathbyspec(dev)) {      if (!getpathbyspec(dev)) {
1707          notSuitablePrintf(entry, "can't find blkid entry for %s\n", dev);          notSuitablePrintf(entry, 0, "can't find blkid entry for %s\n", dev);
1708          return 0;          return 0;
1709      } else      } else
1710   dev = getpathbyspec(dev);   dev = getpathbyspec(dev);
1711    
1712      rootdev = findDiskForRoot();      rootdev = findDiskForRoot();
1713      if (!rootdev) {      if (!rootdev) {
1714          notSuitablePrintf(entry, "can't find root device\n");          notSuitablePrintf(entry, 0, "can't find root device\n");
1715   return 0;   return 0;
1716      }      }
1717    
1718      if (!getuuidbydev(rootdev) || !getuuidbydev(dev)) {      if (!getuuidbydev(rootdev) || !getuuidbydev(dev)) {
1719          notSuitablePrintf(entry, "uuid missing: rootdev %s, dev %s\n",          notSuitablePrintf(entry, 0, "uuid missing: rootdev %s, dev %s\n",
1720   getuuidbydev(rootdev), getuuidbydev(dev));   getuuidbydev(rootdev), getuuidbydev(dev));
1721          free(rootdev);          free(rootdev);
1722          return 0;          return 0;
1723      }      }
1724    
1725      if (strcmp(getuuidbydev(rootdev), getuuidbydev(dev))) {      if (strcmp(getuuidbydev(rootdev), getuuidbydev(dev))) {
1726          notSuitablePrintf(entry, "uuid mismatch: rootdev %s, dev %s\n",          notSuitablePrintf(entry, 0, "uuid mismatch: rootdev %s, dev %s\n",
1727   getuuidbydev(rootdev), getuuidbydev(dev));   getuuidbydev(rootdev), getuuidbydev(dev));
1728   free(rootdev);   free(rootdev);
1729          return 0;          return 0;
1730      }      }
1731    
1732      free(rootdev);      free(rootdev);
1733        notSuitablePrintf(entry, 1, "\n");
1734    
1735      return 1;      return 1;
1736  }  }
# Line 1773  struct singleEntry * findEntryByPath(str Line 1823  struct singleEntry * findEntryByPath(str
1823    
1824      /* check all the lines matching checkType */      /* check all the lines matching checkType */
1825      for (line = entry->lines; line; line = line->next) {      for (line = entry->lines; line; line = line->next) {
1826   line = getLineByType(entry->multiboot && checkType == LT_KERNEL   enum lineType_e ct = checkType;
1827   ? LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER   if (entry->multiboot && checkType == LT_KERNEL)
1828   : checkType, line);      ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER;
1829   if (!line) break;  /* not found in this entry */   else if (checkType & LT_KERNEL)
1830        ct = checkType | LT_KERNEL_EFI;
1831     line = getLineByType(ct, line);
1832     if (!line)
1833        break;  /* not found in this entry */
1834    
1835   if (line && line->type != LT_MENUENTRY &&   if (line && line->type != LT_MENUENTRY &&
1836   line->numElements >= 2) {   line->numElements >= 2) {
# Line 3746  static void traceback(int signum) Line 3800  static void traceback(int signum)
3800      memset(array, '\0', sizeof (array));      memset(array, '\0', sizeof (array));
3801      size = backtrace(array, 40);      size = backtrace(array, 40);
3802    
3803      fprintf(stderr, "grubby recieved SIGSEGV!  Backtrace (%ld):\n",      fprintf(stderr, "grubby received SIGSEGV!  Backtrace (%ld):\n",
3804              (unsigned long)size);              (unsigned long)size);
3805      backtrace_symbols_fd(array, size, STDERR_FILENO);      backtrace_symbols_fd(array, size, STDERR_FILENO);
3806      exit(1);      exit(1);
# Line 3844  int main(int argc, const char ** argv) { Line 3898  int main(int argc, const char ** argv) {
3898   { "initrd", 0, POPT_ARG_STRING, &newKernelInitrd, 0,   { "initrd", 0, POPT_ARG_STRING, &newKernelInitrd, 0,
3899      _("initrd image for the new kernel"), _("initrd-path") },      _("initrd image for the new kernel"), _("initrd-path") },
3900   { "extra-initrd", 'i', POPT_ARG_STRING, NULL, 'i',   { "extra-initrd", 'i', POPT_ARG_STRING, NULL, 'i',
3901      _("auxilliary initrd image for things other than the new kernel"), _("initrd-path") },      _("auxiliary initrd image for things other than the new kernel"), _("initrd-path") },
3902   { "lilo", 0, POPT_ARG_NONE, &configureLilo, 0,   { "lilo", 0, POPT_ARG_NONE, &configureLilo, 0,
3903      _("configure lilo bootloader") },      _("configure lilo bootloader") },
3904   { "make-default", 0, 0, &makeDefault, 0,   { "make-default", 0, 0, &makeDefault, 0,
# Line 3888  int main(int argc, const char ** argv) { Line 3942  int main(int argc, const char ** argv) {
3942    
3943      signal(SIGSEGV, traceback);      signal(SIGSEGV, traceback);
3944    
3945        int i = 0;
3946        for (int j = 1; j < argc; j++)
3947     i += strlen(argv[j]) + 1;
3948        saved_command_line = malloc(i);
3949        if (!saved_command_line) {
3950     fprintf(stderr, "grubby: %m\n");
3951     exit(1);
3952        }
3953        saved_command_line[0] = '\0';
3954        for (int j = 1; j < argc; j++) {
3955     strcat(saved_command_line, argv[j]);
3956     strncat(saved_command_line, j == argc -1 ? "" : " ", 1);
3957        }
3958    
3959      optCon = poptGetContext("grubby", argc, argv, options, 0);      optCon = poptGetContext("grubby", argc, argv, options, 0);
3960      poptReadDefaultConfig(optCon, 1);      poptReadDefaultConfig(optCon, 1);
3961    
# Line 4131  int main(int argc, const char ** argv) { Line 4199  int main(int argc, const char ** argv) {
4199   return 0;   return 0;
4200      }      }
4201    
4202        if (grubConfig == NULL) {
4203     printf("Could not find bootloader configuration file.\n");
4204     exit(1);
4205        }
4206    
4207      config = readConfig(grubConfig, cfi);      config = readConfig(grubConfig, cfi);
4208      if (!config) return 1;      if (!config) return 1;
4209    
# Line 4181  int main(int argc, const char ** argv) { Line 4254  int main(int argc, const char ** argv) {
4254      } else if (displayDefaultIndex) {      } else if (displayDefaultIndex) {
4255          if (config->defaultImage == -1) return 0;          if (config->defaultImage == -1) return 0;
4256          printf("%i\n", config->defaultImage);          printf("%i\n", config->defaultImage);
4257            return 0;
4258    
4259      } else if (kernelInfo)      } else if (kernelInfo)
4260   return displayInfo(config, kernelInfo, bootPrefix);   return displayInfo(config, kernelInfo, bootPrefix);

Legend:
Removed from v.1940  
changed lines
  Added in v.2250