Magellan Linux

Diff of /trunk/grubby/grubby.c

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

revision 3014 by niro, Tue Jun 27 14:34:11 2017 UTC revision 3138 by niro, Tue Jul 7 11:11:04 2020 UTC
# Line 132  struct singleEntry { Line 132  struct singleEntry {
132  #define NEED_DEVTREE (1 << 6)  #define NEED_DEVTREE (1 << 6)
133    
134  #define MAIN_DEFAULT    (1 << 0)  #define MAIN_DEFAULT    (1 << 0)
135    #define FIRST_ENTRY_INDEX    0 /* boot entry index value begin and increment
136       from this initial value */
137    #define NO_DEFAULT_ENTRY    -1 /* indicates that no specific default boot
138       entry was set or currently exists */
139  #define DEFAULT_SAVED       -2  #define DEFAULT_SAVED       -2
140  #define DEFAULT_SAVED_GRUB2 -3  #define DEFAULT_SAVED_GRUB2 -3
141    
# Line 677  struct grubConfig { Line 681  struct grubConfig {
681   int fallbackImage; /* just like defaultImage */   int fallbackImage; /* just like defaultImage */
682   int flags;   int flags;
683   struct configFileInfo *cfi;   struct configFileInfo *cfi;
684     int isModified; /* assumes only one entry added
685       per invocation of grubby */
686  };  };
687    
688  blkid_cache blkid;  blkid_cache blkid;
# Line 695  static int lineWrite(FILE * out, struct Line 701  static int lineWrite(FILE * out, struct
701       struct configFileInfo *cfi);       struct configFileInfo *cfi);
702  static int getNextLine(char **bufPtr, struct singleLine *line,  static int getNextLine(char **bufPtr, struct singleLine *line,
703         struct configFileInfo *cfi);         struct configFileInfo *cfi);
704  static char *getRootSpecifier(char *str);  static size_t getRootSpecifier(const char *str);
705  static void requote(struct singleLine *line, struct configFileInfo *cfi);  static void requote(struct singleLine *line, struct configFileInfo *cfi);
706  static void insertElement(struct singleLine *line,  static void insertElement(struct singleLine *line,
707    const char *item, int insertHere,    const char *item, int insertHere,
# Line 1296  static struct grubConfig *readConfig(con Line 1302  static struct grubConfig *readConfig(con
1302   cfg->theLines = NULL;   cfg->theLines = NULL;
1303   cfg->entries = NULL;   cfg->entries = NULL;
1304   cfg->fallbackImage = 0;   cfg->fallbackImage = 0;
1305     cfg->isModified = 0;
1306    
1307   /* copy everything we have */   /* copy everything we have */
1308   while (*head) {   while (*head) {
# Line 1615  static struct grubConfig *readConfig(con Line 1622  static struct grubConfig *readConfig(con
1622   *end == ' ' || *end == '\t'))   *end == ' ' || *end == '\t'))
1623   end++;   end++;
1624   if (*end)   if (*end)
1625   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1626   } else if (defaultLine->numElements == 3) {   } else if (defaultLine->numElements == 3) {
1627   char *value = defaultLine->elements[2].item;   char *value = defaultLine->elements[2].item;
1628   while (*value && (*value == '"' ||   while (*value && (*value == '"' ||
# Line 1628  static struct grubConfig *readConfig(con Line 1635  static struct grubConfig *readConfig(con
1635   *end == ' ' || *end == '\t'))   *end == ' ' || *end == '\t'))
1636   end++;   end++;
1637   if (*end)   if (*end)
1638   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1639   }   }
1640   } else if (cfi->defaultSupportSaved &&   } else if (cfi->defaultSupportSaved &&
1641     !strncmp(defaultLine->elements[1].item, "saved",     !strncmp(defaultLine->elements[1].item, "saved",
# Line 1638  static struct grubConfig *readConfig(con Line 1645  static struct grubConfig *readConfig(con
1645   cfg->defaultImage =   cfg->defaultImage =
1646      strtol(defaultLine->elements[1].item, &end, 10);      strtol(defaultLine->elements[1].item, &end, 10);
1647   if (*end)   if (*end)
1648   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1649   } else if (defaultLine->numElements >= 2) {   } else if (defaultLine->numElements >= 2) {
1650   int i = 0;   int i = 0;
1651   while ((entry = findEntryByIndex(cfg, i))) {   while ((entry = findEntryByIndex(cfg, i))) {
# Line 1666  static struct grubConfig *readConfig(con Line 1673  static struct grubConfig *readConfig(con
1673   if (entry) {   if (entry) {
1674   cfg->defaultImage = i;   cfg->defaultImage = i;
1675   } else {   } else {
1676   cfg->defaultImage = -1;   cfg->defaultImage = NO_DEFAULT_ENTRY;
1677   }   }
1678   }   }
1679   } else if (cfg->cfi->defaultIsSaved && cfg->cfi->getEnv) {   } else if (cfg->cfi->defaultIsSaved && cfg->cfi->getEnv) {
# Line 1683  static struct grubConfig *readConfig(con Line 1690  static struct grubConfig *readConfig(con
1690   cfg->defaultImage = index;   cfg->defaultImage = index;
1691   }   }
1692   } else {   } else {
1693   cfg->defaultImage = 0;   cfg->defaultImage = FIRST_ENTRY_INDEX;
1694   }   }
1695    
1696   return cfg;   return cfg;
# Line 1703  static void writeDefault(FILE * out, cha Line 1710  static void writeDefault(FILE * out, cha
1710   fprintf(out, "%sdefault%ssaved\n", indent, separator);   fprintf(out, "%sdefault%ssaved\n", indent, separator);
1711   else if (cfg->cfi->defaultIsSaved) {   else if (cfg->cfi->defaultIsSaved) {
1712   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);
1713   if (cfg->defaultImage >= 0 && cfg->cfi->setEnv) {   if (cfg->defaultImage >= FIRST_ENTRY_INDEX && cfg->cfi->setEnv) {
1714   char *title;   char *title;
1715   entry = findEntryByIndex(cfg, cfg->defaultImage);   int trueIndex, currentIndex;
1716    
1717     trueIndex = 0;
1718     currentIndex = 0;
1719    
1720     while ((entry = findEntryByIndex(cfg, currentIndex))) {
1721     if (!entry->skip) {
1722     if (trueIndex == cfg->defaultImage) {
1723     break;
1724     }
1725     trueIndex++;
1726     }
1727     currentIndex++;
1728     }
1729   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
1730   if (!line)   if (!line)
1731   line = getLineByType(LT_TITLE, entry->lines);   line = getLineByType(LT_TITLE, entry->lines);
# Line 1716  static void writeDefault(FILE * out, cha Line 1736  static void writeDefault(FILE * out, cha
1736   "saved_entry", title);   "saved_entry", title);
1737   }   }
1738   }   }
1739   } else if (cfg->defaultImage > -1) {   } else if (cfg->defaultImage >= FIRST_ENTRY_INDEX) {
1740   if (cfg->cfi->defaultIsIndex) {   if (cfg->cfi->defaultIsIndex) {
1741   if (cfg->cfi->defaultIsVariable) {   if (cfg->cfi->defaultIsVariable) {
1742   fprintf(out, "%sset default=\"%d\"\n", indent,   fprintf(out, "%sset default=\"%d\"\n", indent,
# Line 1772  static int writeConfig(struct grubConfig Line 1792  static int writeConfig(struct grubConfig
1792   int needs = MAIN_DEFAULT;   int needs = MAIN_DEFAULT;
1793   struct stat sb;   struct stat sb;
1794   int i;   int i;
1795     int rc = 0;
1796    
1797   if (!strcmp(outName, "-")) {   if (!strcmp(outName, "-")) {
1798   out = stdout;   out = stdout;
# Line 1886  static int writeConfig(struct grubConfig Line 1907  static int writeConfig(struct grubConfig
1907   }   }
1908    
1909   if (tmpOutName) {   if (tmpOutName) {
1910   if (rename(tmpOutName, outName)) {   /* write userspace buffers */
1911   fprintf(stderr,   if (fflush(out))
1912   _("grubby: error moving %s to %s: %s\n"),   rc = 1;
1913   tmpOutName, outName, strerror(errno));  
1914   unlink(outName);   /* purge the write-back cache with fsync() */
1915   return 1;   if (fsync(fileno(out)))
1916     rc = 1;
1917    
1918     if (fclose(out))
1919     rc = 1;
1920    
1921     if (rc == 0 && rename(tmpOutName, outName)) {
1922     unlink(tmpOutName);
1923     rc = 1;
1924   }   }
1925    
1926     /* fsync() the destination directory after rename */
1927     if (rc == 0) {
1928     int dirfd;
1929    
1930     dirfd = open(dirname(strdupa(outName)), O_RDONLY);
1931     if (dirfd < 0)
1932     rc = 1;
1933     else if (fsync(dirfd))
1934     rc = 1;
1935    
1936     if (dirfd >= 0)
1937     close(dirfd);
1938     }
1939    
1940     if (rc == 1)
1941     fprintf(stderr,
1942     _("grubby: error flushing data: %m\n"));
1943   }   }
1944    
1945   return 0;   return rc;
1946  }  }
1947    
1948  static int numEntries(struct grubConfig *cfg)  static int numEntries(struct grubConfig *cfg)
# Line 2078  int suitableImage(struct singleEntry *en Line 2125  int suitableImage(struct singleEntry *en
2125   char *fullName;   char *fullName;
2126   int i;   int i;
2127   char *dev;   char *dev;
2128   char *rootspec;   size_t rs;
2129   char *rootdev;   char *rootdev;
2130    
2131   if (skipRemoved && entry->skip) {   if (skipRemoved && entry->skip) {
# Line 2106  int suitableImage(struct singleEntry *en Line 2153  int suitableImage(struct singleEntry *en
2153    
2154   fullName = alloca(strlen(bootPrefix) +   fullName = alloca(strlen(bootPrefix) +
2155    strlen(line->elements[1].item) + 1);    strlen(line->elements[1].item) + 1);
2156   rootspec = getRootSpecifier(line->elements[1].item);   rs = getRootSpecifier(line->elements[1].item);
  int rootspec_offset = rootspec ? strlen(rootspec) : 0;  
2157   int hasslash = endswith(bootPrefix, '/') ||   int hasslash = endswith(bootPrefix, '/') ||
2158      beginswith(line->elements[1].item + rootspec_offset, '/');      beginswith(line->elements[1].item + rs, '/');
2159   sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/",   sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/",
2160   line->elements[1].item + rootspec_offset);   line->elements[1].item + rs);
2161   if (access(fullName, R_OK)) {   if (access(fullName, R_OK)) {
2162   notSuitablePrintf(entry, 0, "access to %s failed\n", fullName);   notSuitablePrintf(entry, 0, "access to %s failed\n", fullName);
2163   return 0;   return 0;
# Line 2203  struct singleEntry *findEntryByPath(stru Line 2249  struct singleEntry *findEntryByPath(stru
2249   struct singleLine *line;   struct singleLine *line;
2250   int i;   int i;
2251   char *chptr;   char *chptr;
  char *rootspec = NULL;  
2252   enum lineType_e checkType = LT_KERNEL;   enum lineType_e checkType = LT_KERNEL;
2253    
2254   if (isdigit(*kernel)) {   if (isdigit(*kernel)) {
# Line 2308  struct singleEntry *findEntryByPath(stru Line 2353  struct singleEntry *findEntryByPath(stru
2353    
2354   if (line && line->type != LT_MENUENTRY &&   if (line && line->type != LT_MENUENTRY &&
2355      line->numElements >= 2) {      line->numElements >= 2) {
2356   rootspec =   if (!strcmp(line->elements[1].item +
2357      getRootSpecifier(line->elements[1].   getRootSpecifier(
2358       item);   line->elements[1].item),
2359   if (!strcmp   kernel + strlen(prefix)))
     (line->elements[1].item +  
      ((rootspec !=  
        NULL) ? strlen(rootspec) : 0),  
      kernel + strlen(prefix)))  
2360   break;   break;
2361   }   }
2362   if (line->type == LT_MENUENTRY &&   if (line->type == LT_MENUENTRY &&
# Line 2420  struct singleEntry *findTemplate(struct Line 2461  struct singleEntry *findTemplate(struct
2461   }   }
2462   }   }
2463   }   }
2464   } else if (cfg->defaultImage > -1) {   } else if (cfg->defaultImage >= FIRST_ENTRY_INDEX) {
2465   entry = findEntryByIndex(cfg, cfg->defaultImage);   entry = findEntryByIndex(cfg, cfg->defaultImage);
2466   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {   if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
2467   if (indexPtr)   if (indexPtr)
# Line 2432  struct singleEntry *findTemplate(struct Line 2473  struct singleEntry *findTemplate(struct
2473   index = 0;   index = 0;
2474   while ((entry = findEntryByIndex(cfg, index))) {   while ((entry = findEntryByIndex(cfg, index))) {
2475   if (suitableImage(entry, prefix, skipRemoved, flags)) {   if (suitableImage(entry, prefix, skipRemoved, flags)) {
2476   int j;   int j, unmodifiedIndex;
2477   for (j = 0; j < index; j++) {  
2478     unmodifiedIndex = index;
2479    
2480     for (j = 0; j < unmodifiedIndex; j++) {
2481   entry2 = findEntryByIndex(cfg, j);   entry2 = findEntryByIndex(cfg, j);
2482   if (entry2->skip)   if (entry2->skip)
2483   index--;   index--;
# Line 2494  void markRemovedImage(struct grubConfig Line 2538  void markRemovedImage(struct grubConfig
2538   entry->skip = 1;   entry->skip = 1;
2539  }  }
2540    
2541  void setDefaultImage(struct grubConfig *config, int hasNew,  void setDefaultImage(struct grubConfig *config, int isAddingBootEntry,
2542       const char *defaultKernelPath, int newIsDefault,       const char *defaultKernelPath, int newBootEntryIsDefault,
2543       const char *prefix, int flags, int index)       const char *prefix, int flags,
2544  {       int newDefaultBootEntryIndex, int newBootEntryIndex)
2545   struct singleEntry *entry, *entry2, *newDefault;  {
2546   int i, j;   struct singleEntry *bootEntry, *newDefault;
2547     int indexToVerify, firstKernelEntryIndex, currentLookupIndex;
2548   if (newIsDefault) {  
2549   config->defaultImage = 0;          /* initialize */
2550            currentLookupIndex = FIRST_ENTRY_INDEX;
2551    
2552     /* handle the two cases where the user explictly picks the default
2553     * boot entry index as it would exist post-modification */
2554    
2555     /* Case 1: user chose to make the latest boot entry the default */
2556     if (newBootEntryIsDefault) {
2557     config->defaultImage = newBootEntryIndex;
2558   return;   return;
2559   } else if ((index >= 0) && config->cfi->defaultIsIndex) {   }
2560   if (findEntryByIndex(config, index))  
2561   config->defaultImage = index;   /* Case 2: user picked an arbitrary index as the default boot entry */
2562   else   if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX) {
2563   config->defaultImage = -1;   indexToVerify = newDefaultBootEntryIndex;
2564   return;  
2565   } else if (defaultKernelPath) {   /* user chose to make latest boot entry the default */
2566   i = 0;   if (newDefaultBootEntryIndex == newBootEntryIndex) {
2567   if (findEntryByPath(config, defaultKernelPath, prefix, &i)) {   config->defaultImage = newBootEntryIndex;
  config->defaultImage = i;  
  } else {  
  config->defaultImage = -1;  
2568   return;   return;
2569   }   }
  }  
2570    
2571   /* defaultImage now points to what we'd like to use, but before any   /* the user picks the default index based on the
2572   * order changes */   * order of the bootloader configuration after
2573   if ((config->defaultImage == DEFAULT_SAVED) ||   * modification; ensure we are checking for the
2574      (config->defaultImage == DEFAULT_SAVED_GRUB2))   * existence of the correct entry */
2575   /* default is set to saved, we don't want to change it */   if (newBootEntryIndex < newDefaultBootEntryIndex) {
2576     if (!config->isModified)
2577     indexToVerify--;
2578     }
2579    
2580     /* verify the user selected index will exist */
2581     if (findEntryByIndex(config, indexToVerify)) {
2582     config->defaultImage = newDefaultBootEntryIndex;
2583     } else {
2584     config->defaultImage = NO_DEFAULT_ENTRY;
2585     }
2586    
2587   return;   return;
2588     }
2589    
2590   if (config->defaultImage > -1)   /* handle cases where the index value may shift */
  entry = findEntryByIndex(config, config->defaultImage);  
  else  
  entry = NULL;  
2591    
2592   if (entry && !entry->skip) {   /* check validity of existing default or first-entry-found
2593   /* we can preserve the default */     selection */
2594   if (hasNew)   if (defaultKernelPath) {
2595   config->defaultImage++;                  /* we must initialize this */
2596                    firstKernelEntryIndex = 0;
2597     /* user requested first-entry-found */
2598     if (!findEntryByPath(config, defaultKernelPath,
2599         prefix, &firstKernelEntryIndex)) {
2600     /* don't change default if can't find match */
2601     config->defaultImage = NO_DEFAULT_ENTRY;
2602     return;
2603     }
2604    
2605   /* count the number of entries erased before this one */   config->defaultImage = firstKernelEntryIndex;
2606   for (j = 0; j < config->defaultImage; j++) {  
2607   entry2 = findEntryByIndex(config, j);   /* this is where we start looking for decrement later */
2608   if (entry2->skip)   currentLookupIndex = config->defaultImage;
2609   config->defaultImage--;  
2610     if (isAddingBootEntry && !config->isModified &&
2611        (newBootEntryIndex < config->defaultImage)) {
2612     /* increment because new entry added before default */
2613     config->defaultImage++;
2614   }   }
  } else if (hasNew) {  
  config->defaultImage = 0;  
2615   } else {   } else {
2616   /* Either we just erased the default (or the default line was                  /* check to see if the default is stored in the environment */
2617   * bad to begin with) and didn't put a new one in. We'll use                  if (config->defaultImage < FIRST_ENTRY_INDEX) {
2618   * the first valid image. */                      if (config->defaultImage == DEFAULT_SAVED || config->defaultImage == DEFAULT_SAVED_GRUB2)
2619                        {
2620                            if (config->cfi->defaultIsSaved) {
2621                                if (config->cfi->getEnv) {
2622                                    char *defaultTitle = config->cfi->getEnv(config->cfi, "saved_entry");
2623    
2624                                    if (defaultTitle) {
2625                                        if (isnumber(defaultTitle)) {
2626                                            currentLookupIndex = atoi(defaultTitle);
2627                                        } else {
2628                                            findEntryByTitle(config, defaultTitle, &currentLookupIndex);
2629                                        }
2630                                        /* set the default Image to an actual index */
2631                                        config->defaultImage = currentLookupIndex;
2632                                    }
2633                                }
2634                             }
2635                        }
2636                    } else {
2637                            /* use pre-existing default entry from the file*/
2638                            currentLookupIndex = config->defaultImage;
2639                    }
2640    
2641     if (isAddingBootEntry
2642        && (newBootEntryIndex <= config->defaultImage)) {
2643     config->defaultImage++;
2644    
2645     if (config->isModified) {
2646     currentLookupIndex++;
2647     }
2648     }
2649     }
2650    
2651     /* sanity check - is this entry index valid? */
2652     bootEntry = findEntryByIndex(config, currentLookupIndex);
2653    
2654     if ((bootEntry && bootEntry->skip) || !bootEntry) {
2655     /* entry is to be skipped or is invalid */
2656     if (isAddingBootEntry) {
2657     config->defaultImage = newBootEntryIndex;
2658     return;
2659     }
2660   newDefault =   newDefault =
2661      findTemplate(config, prefix, &config->defaultImage, 1,      findTemplate(config, prefix, &config->defaultImage, 1,
2662   flags);   flags);
2663   if (!newDefault)   if (!newDefault) {
2664   config->defaultImage = -1;   config->defaultImage = NO_DEFAULT_ENTRY;
2665     }
2666    
2667     return;
2668     }
2669    
2670     currentLookupIndex--;
2671    
2672     /* decrement index by the total number of entries deleted */
2673    
2674     for (indexToVerify = currentLookupIndex;
2675         indexToVerify >= FIRST_ENTRY_INDEX; indexToVerify--) {
2676    
2677     bootEntry = findEntryByIndex(config, indexToVerify);
2678    
2679     if (bootEntry && bootEntry->skip) {
2680     config->defaultImage--;
2681     }
2682   }   }
2683  }  }
2684    
# Line 2582  void setFallbackImage(struct grubConfig Line 2707  void setFallbackImage(struct grubConfig
2707   }   }
2708  }  }
2709    
2710  void displayEntry(struct singleEntry *entry, const char *prefix, int index)  void displayEntry(struct grubConfig *config, struct singleEntry *entry, const char *prefix, int index)
2711  {  {
2712   struct singleLine *line;   struct singleLine *line;
2713   char *root = NULL;   char *root = NULL;
# Line 2678  void displayEntry(struct singleEntry *en Line 2803  void displayEntry(struct singleEntry *en
2803    
2804   line = getLineByType(LT_TITLE, entry->lines);   line = getLineByType(LT_TITLE, entry->lines);
2805   if (line) {   if (line) {
2806   printf("title=%s\n", line->elements[1].item);                  char *entryTitle;
2807                    /* if we can extractTitle, then it's a zipl config and
2808                     * if not then we go ahead with what's existed prior */
2809                    entryTitle = extractTitle(config, line);
2810                    if (!entryTitle) {
2811                        entryTitle=line->elements[1].item;
2812                    }
2813     printf("title=%s\n", entryTitle);
2814   } else {   } else {
2815   char *title;   char *title;
2816   line = getLineByType(LT_MENUENTRY, entry->lines);   line = getLineByType(LT_MENUENTRY, entry->lines);
# Line 3094  int displayInfo(struct grubConfig *confi Line 3226  int displayInfo(struct grubConfig *confi
3226   printf("lba\n");   printf("lba\n");
3227   }   }
3228    
3229   displayEntry(entry, prefix, i);   displayEntry(config, entry, prefix, i);
3230    
3231   i++;   i++;
3232   while ((entry = findEntryByPath(config, kernel, prefix, &i))) {   while ((entry = findEntryByPath(config, kernel, prefix, &i))) {
3233   displayEntry(entry, prefix, i);   displayEntry(config, entry, prefix, i);
3234   i++;   i++;
3235   }   }
3236    
# Line 3133  struct singleLine *addLineTmpl(struct si Line 3265  struct singleLine *addLineTmpl(struct si
3265      type & (LT_HYPER | LT_KERNEL | LT_MBMODULE | LT_INITRD |      type & (LT_HYPER | LT_KERNEL | LT_MBMODULE | LT_INITRD |
3266      LT_KERNEL_EFI | LT_INITRD_EFI | LT_KERNEL_16 |      LT_KERNEL_EFI | LT_INITRD_EFI | LT_KERNEL_16 |
3267      LT_INITRD_16)) {      LT_INITRD_16)) {
3268   char *rootspec =   size_t rs = getRootSpecifier(tmplLine->elements[1].item);
3269      getRootSpecifier(tmplLine->elements[1].item);   if (rs > 0) {
  if (rootspec != NULL) {  
3270   free(newLine->elements[1].item);   free(newLine->elements[1].item);
3271   newLine->elements[1].item =   newLine->elements[1].item = sdupprintf(
3272      sdupprintf("%s%s", rootspec, val);   "%.*s%s", (int) rs,
3273     tmplLine->elements[1].item, val);
3274   }   }
3275   }   }
3276   }   }
# Line 3428  static void removeElement(struct singleL Line 3560  static void removeElement(struct singleL
3560   line->numElements--;   line->numElements--;
3561  }  }
3562    
3563  int argMatch(const char *one, const char *two)  static int argNameMatch(const char *one, const char *two)
3564  {  {
3565   char *first, *second;   char *first, *second;
3566   char *chptr;   char *chptra, *chptrb;
3567     int rc;
3568    
3569   first = strcpy(alloca(strlen(one) + 1), one);   first = strcpy(alloca(strlen(one) + 1), one);
3570   second = strcpy(alloca(strlen(two) + 1), two);   second = strcpy(alloca(strlen(two) + 1), two);
3571    
3572   chptr = strchr(first, '=');   chptra = strchr(first, '=');
3573   if (chptr)   if (chptra)
3574   *chptr = '\0';   *chptra = '\0';
3575    
3576     chptrb = strchr(second, '=');
3577     if (chptrb)
3578     *chptrb = '\0';
3579    
3580     rc = strcmp(first, second);
3581    
3582     if (chptra)
3583     *chptra = '=';
3584     if (chptrb)
3585     *chptrb = '=';
3586    
3587     return rc;
3588    }
3589    
3590   chptr = strchr(second, '=');  static int argHasValue(const char *arg)
3591    {
3592     char *chptr;
3593    
3594     chptr = strchr(arg, '=');
3595   if (chptr)   if (chptr)
3596   *chptr = '\0';   return 1;
3597     return 0;
3598    }
3599    
3600    static int argValueMatch(const char *one, const char *two)
3601    {
3602     char *first, *second;
3603     char *chptra, *chptrb;
3604    
3605     first = strcpy(alloca(strlen(one) + 1), one);
3606     second = strcpy(alloca(strlen(two) + 1), two);
3607    
3608     chptra = strchr(first, '=');
3609     if (chptra)
3610     chptra += 1;
3611    
3612     chptrb = strchr(second, '=');
3613     if (chptrb)
3614     chptrb += 1;
3615    
3616   return strcmp(first, second);   if (!chptra && !chptrb)
3617     return 0;
3618     else if (!chptra)
3619     return *chptrb - 0;
3620     else if (!chptrb)
3621     return 0 - *chptra;
3622     else
3623     return strcmp(chptra, chptrb);
3624  }  }
3625    
3626  int updateActualImage(struct grubConfig *cfg, const char *image,  int updateActualImage(struct grubConfig *cfg, const char *image,
# Line 3588  int updateActualImage(struct grubConfig Line 3764  int updateActualImage(struct grubConfig
3764   }   }
3765   if (usedElements[i])   if (usedElements[i])
3766   continue;   continue;
3767   if (!argMatch(line->elements[i].item, *arg)) {   if (!argNameMatch(line->elements[i].item, *arg)) {
3768   usedElements[i] = 1;   usedElements[i] = 1;
3769   break;   break;
3770   }   }
# Line 3647  int updateActualImage(struct grubConfig Line 3823  int updateActualImage(struct grubConfig
3823      !strcmp(line->elements[i].item, "--"))      !strcmp(line->elements[i].item, "--"))
3824   /* reached the end of hyper args, stop here */   /* reached the end of hyper args, stop here */
3825   break;   break;
3826   if (!argMatch(line->elements[i].item, *arg)) {   if (!argNameMatch(line->elements[i].item, *arg)) {
3827   removeElement(line, i);   if (!argHasValue(*arg) ||
3828   break;      !argValueMatch(line->elements[i].item, *arg)) {
3829     removeElement(line, i);
3830     break;
3831     }
3832   }   }
3833   }   }
3834   /* handle removing LT_ROOT line too */   /* handle removing LT_ROOT line too */
# Line 4143  int checkForElilo(struct grubConfig *con Line 4322  int checkForElilo(struct grubConfig *con
4322   return 1;   return 1;
4323  }  }
4324    
4325  static char *getRootSpecifier(char *str)  static size_t getRootSpecifier(const char *str)
4326  {  {
4327   char *idx, *rootspec = NULL;   size_t rs = 0;
4328    
4329   if (*str == '(') {   if (*str == '(') {
4330   idx = rootspec = strdup(str);   for (; str[rs] != ')' && !isspace(str[rs]); rs++) {
4331   while (*idx && (*idx != ')') && (!isspace(*idx)))   if (!str[rs])
4332   idx++;   return rs;
4333   *(++idx) = '\0';   }
4334     rs++;
4335   }   }
4336   return rootspec;  
4337     return rs;
4338  }  }
4339    
4340  static char *getInitrdVal(struct grubConfig *config,  static char *getInitrdVal(struct grubConfig *config,
# Line 4725  int addNewKernel(struct grubConfig *conf Line 4906  int addNewKernel(struct grubConfig *conf
4906   }   }
4907    
4908   if (updateImage(config, indexs, prefix, newKernelArgs, NULL,   if (updateImage(config, indexs, prefix, newKernelArgs, NULL,
4909   newMBKernelArgs, NULL))   newMBKernelArgs, NULL)) {
4910     config->isModified = 1;
4911   return 1;   return 1;
4912     }
4913    
4914   return 0;   return 0;
4915  }  }
# Line 4967  int main(int argc, const char **argv) Line 5150  int main(int argc, const char **argv)
5150   if (!cfi) {   if (!cfi) {
5151   if (grub2FindConfig(&grub2ConfigType)) {   if (grub2FindConfig(&grub2ConfigType)) {
5152   cfi = &grub2ConfigType;   cfi = &grub2ConfigType;
5153     configureGrub2 = 1;
5154   if (envPath)   if (envPath)
5155   cfi->envFile = envPath;   cfi->envFile = envPath;
5156   } else   } else {
5157  #ifdef __ia64__  #ifdef __ia64__
5158   cfi = &eliloConfigType;   cfi = &eliloConfigType;
5159  #elif __powerpc__   configureLilo = 1;
5160    #elif defined(__powerpc__)
5161   cfi = &yabootConfigType;   cfi = &yabootConfigType;
5162  #elif __sparc__   configureYaboot = 1;
5163    #elif defined(__sparc__)
5164   cfi = &siloConfigType;   cfi = &siloConfigType;
5165  #elif __s390__   configureSilo = 1;
5166    #elif defined(__s390__) || defined(__s390x__)
5167   cfi = &ziplConfigType;   cfi = &ziplConfigType;
5168  #elif __s390x__   configureZipl = 1;
  cfi = &ziplConfigtype;  
5169  #else  #else
5170   cfi = &grubConfigType;   cfi = &grubConfigType;
5171     configureGrub = 1;
5172  #endif  #endif
5173     }
5174   }   }
5175    
5176   if (!grubConfig) {   if (!grubConfig) {
# Line 5176  int main(int argc, const char **argv) Line 5364  int main(int argc, const char **argv)
5364   if (displayDefault) {   if (displayDefault) {
5365   struct singleLine *line;   struct singleLine *line;
5366   struct singleEntry *entry;   struct singleEntry *entry;
5367   char *rootspec;   size_t rs;
5368    
5369   if (config->defaultImage == -1)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5370   return 0;   return 0;
5371   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
5372      cfi->defaultIsSaved)      cfi->defaultIsSaved)
5373   config->defaultImage = 0;   config->defaultImage = FIRST_ENTRY_INDEX;
5374   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
5375   if (!entry)   if (!entry)
5376   return 0;   return 0;
# Line 5195  int main(int argc, const char **argv) Line 5383  int main(int argc, const char **argv)
5383   if (!line)   if (!line)
5384   return 0;   return 0;
5385    
5386   rootspec = getRootSpecifier(line->elements[1].item);   rs = getRootSpecifier(line->elements[1].item);
5387   printf("%s%s\n", bootPrefix, line->elements[1].item +   printf("%s%s\n", bootPrefix, line->elements[1].item + rs);
        ((rootspec != NULL) ? strlen(rootspec) : 0));  
5388    
5389   return 0;   return 0;
5390    
# Line 5205  int main(int argc, const char **argv) Line 5392  int main(int argc, const char **argv)
5392   struct singleLine *line;   struct singleLine *line;
5393   struct singleEntry *entry;   struct singleEntry *entry;
5394    
5395   if (config->defaultImage == -1)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5396   return 0;   return 0;
5397   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
5398      cfi->defaultIsSaved)      cfi->defaultIsSaved)
5399   config->defaultImage = 0;   config->defaultImage = FIRST_ENTRY_INDEX;
5400   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
5401   if (!entry)   if (!entry)
5402   return 0;   return 0;
# Line 5239  int main(int argc, const char **argv) Line 5426  int main(int argc, const char **argv)
5426   return 0;   return 0;
5427    
5428   } else if (displayDefaultIndex) {   } else if (displayDefaultIndex) {
5429   if (config->defaultImage == -1)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5430   return 0;   return 0;
5431   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
5432      cfi->defaultIsSaved)      cfi->defaultIsSaved)
5433   config->defaultImage = 0;   config->defaultImage = FIRST_ENTRY_INDEX;
5434   printf("%i\n", config->defaultImage);   printf("%i\n", config->defaultImage);
5435   return 0;   return 0;
5436    
# Line 5259  int main(int argc, const char **argv) Line 5446  int main(int argc, const char **argv)
5446   markRemovedImage(config, removeKernelPath, bootPrefix);   markRemovedImage(config, removeKernelPath, bootPrefix);
5447   markRemovedImage(config, removeMBKernel, bootPrefix);   markRemovedImage(config, removeMBKernel, bootPrefix);
5448   setDefaultImage(config, newKernelPath != NULL, defaultKernel,   setDefaultImage(config, newKernelPath != NULL, defaultKernel,
5449   makeDefault, bootPrefix, flags, defaultIndex);   makeDefault, bootPrefix, flags, defaultIndex,
5450     newIndex);
5451   setFallbackImage(config, newKernelPath != NULL);   setFallbackImage(config, newKernelPath != NULL);
5452   if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,   if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
5453   removeArgs, newMBKernelArgs, removeMBKernelArgs))   removeArgs, newMBKernelArgs, removeMBKernelArgs))

Legend:
Removed from v.3014  
changed lines
  Added in v.3138