Magellan Linux

Diff of /trunk/grubby/grubby.c

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

revision 3021 by niro, Tue Jun 27 14:39:37 2017 UTC revision 3138 by niro, Tue Jul 7 11:11:04 2020 UTC
# Line 701  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 1712  static void writeDefault(FILE * out, cha Line 1712  static void writeDefault(FILE * out, cha
1712   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);   fprintf(out, "%sset default=\"${saved_entry}\"\n", indent);
1713   if (cfg->defaultImage >= FIRST_ENTRY_INDEX && 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 1779  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 1893  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 2085  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 2113  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 2210  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 2315  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 2439  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 2509  void setDefaultImage(struct grubConfig * Line 2546  void setDefaultImage(struct grubConfig *
2546   struct singleEntry *bootEntry, *newDefault;   struct singleEntry *bootEntry, *newDefault;
2547   int indexToVerify, firstKernelEntryIndex, currentLookupIndex;   int indexToVerify, firstKernelEntryIndex, currentLookupIndex;
2548    
2549            /* initialize */
2550            currentLookupIndex = FIRST_ENTRY_INDEX;
2551    
2552   /* handle the two cases where the user explictly picks the default   /* handle the two cases where the user explictly picks the default
2553   * boot entry index as it would exist post-modification */   * boot entry index as it would exist post-modification */
2554    
# Line 2519  void setDefaultImage(struct grubConfig * Line 2559  void setDefaultImage(struct grubConfig *
2559   }   }
2560    
2561   /* Case 2: user picked an arbitrary index as the default boot entry */   /* Case 2: user picked an arbitrary index as the default boot entry */
2562   if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX   if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX) {
     && config->cfi->defaultIsIndex) {  
2563   indexToVerify = newDefaultBootEntryIndex;   indexToVerify = newDefaultBootEntryIndex;
2564    
2565   /* user chose to make latest boot entry the default */   /* user chose to make latest boot entry the default */
# Line 2553  void setDefaultImage(struct grubConfig * Line 2592  void setDefaultImage(struct grubConfig *
2592   /* check validity of existing default or first-entry-found   /* check validity of existing default or first-entry-found
2593     selection */     selection */
2594   if (defaultKernelPath) {   if (defaultKernelPath) {
2595                    /* we must initialize this */
2596                    firstKernelEntryIndex = 0;
2597   /* user requested first-entry-found */   /* user requested first-entry-found */
2598   if (!findEntryByPath(config, defaultKernelPath,   if (!findEntryByPath(config, defaultKernelPath,
2599       prefix, &firstKernelEntryIndex)) {       prefix, &firstKernelEntryIndex)) {
# Line 2572  void setDefaultImage(struct grubConfig * Line 2613  void setDefaultImage(struct grubConfig *
2613   config->defaultImage++;   config->defaultImage++;
2614   }   }
2615   } else {   } else {
2616   /* use pre-existing default entry */                  /* check to see if the default is stored in the environment */
2617   currentLookupIndex = config->defaultImage;                  if (config->defaultImage < FIRST_ENTRY_INDEX) {
2618                        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   if (isAddingBootEntry
2642      && (newBootEntryIndex <= config->defaultImage)) {      && (newBootEntryIndex <= config->defaultImage)) {
# Line 2644  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 2740  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 3156  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 3195  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 3490  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    static int argHasValue(const char *arg)
3591    {
3592     char *chptr;
3593    
3594   chptr = strchr(second, '=');   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   return strcmp(first, second);   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     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 3650  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 3709  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 4205  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 5031  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 5240  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 == NO_DEFAULT_ENTRY)   if (config->defaultImage == NO_DEFAULT_ENTRY)
5370   return 0;   return 0;
# Line 5259  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    

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