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; |
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) { |
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); |
2452 |
index = 0; |
index = 0; |
2453 |
while ((entry = findEntryByIndex(cfg, index))) { |
while ((entry = findEntryByIndex(cfg, index))) { |
2454 |
if (suitableImage(entry, prefix, skipRemoved, flags)) { |
if (suitableImage(entry, prefix, skipRemoved, flags)) { |
2455 |
int j; |
int j, unmodifiedIndex; |
2456 |
for (j = 0; j < index; j++) { |
|
2457 |
|
unmodifiedIndex = index; |
2458 |
|
|
2459 |
|
for (j = 0; j < unmodifiedIndex; j++) { |
2460 |
entry2 = findEntryByIndex(cfg, j); |
entry2 = findEntryByIndex(cfg, j); |
2461 |
if (entry2->skip) |
if (entry2->skip) |
2462 |
index--; |
index--; |
2517 |
entry->skip = 1; |
entry->skip = 1; |
2518 |
} |
} |
2519 |
|
|
2520 |
void setDefaultImage(struct grubConfig *config, int isUserSpecifiedKernelPath, |
void setDefaultImage(struct grubConfig *config, int isAddingBootEntry, |
2521 |
const char *defaultKernelPath, int newBootEntryIsDefault, |
const char *defaultKernelPath, int newBootEntryIsDefault, |
2522 |
const char *prefix, int flags, int newDefaultBootEntryIndex) |
const char *prefix, int flags, |
2523 |
|
int newDefaultBootEntryIndex, int newBootEntryIndex) |
2524 |
{ |
{ |
2525 |
struct singleEntry *entry, *entry2, *newDefault; |
struct singleEntry *bootEntry, *newDefault; |
2526 |
int i, j; |
int indexToVerify, firstKernelEntryIndex, currentLookupIndex; |
2527 |
|
|
2528 |
|
/* initialize */ |
2529 |
|
currentLookupIndex = FIRST_ENTRY_INDEX; |
2530 |
|
|
2531 |
|
/* handle the two cases where the user explictly picks the default |
2532 |
|
* boot entry index as it would exist post-modification */ |
2533 |
|
|
2534 |
|
/* Case 1: user chose to make the latest boot entry the default */ |
2535 |
if (newBootEntryIsDefault) { |
if (newBootEntryIsDefault) { |
2536 |
config->defaultImage = FIRST_ENTRY_INDEX; |
config->defaultImage = newBootEntryIndex; |
2537 |
return; |
return; |
2538 |
} else if ((newDefaultBootEntryIndex >= 0) && config->cfi->defaultIsIndex) { |
} |
2539 |
if (findEntryByIndex(config, newDefaultBootEntryIndex)) |
|
2540 |
|
/* Case 2: user picked an arbitrary index as the default boot entry */ |
2541 |
|
if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX |
2542 |
|
&& config->cfi->defaultIsIndex) { |
2543 |
|
indexToVerify = newDefaultBootEntryIndex; |
2544 |
|
|
2545 |
|
/* user chose to make latest boot entry the default */ |
2546 |
|
if (newDefaultBootEntryIndex == newBootEntryIndex) { |
2547 |
|
config->defaultImage = newBootEntryIndex; |
2548 |
|
return; |
2549 |
|
} |
2550 |
|
|
2551 |
|
/* the user picks the default index based on the |
2552 |
|
* order of the bootloader configuration after |
2553 |
|
* modification; ensure we are checking for the |
2554 |
|
* existence of the correct entry */ |
2555 |
|
if (newBootEntryIndex < newDefaultBootEntryIndex) { |
2556 |
|
if (!config->isModified) |
2557 |
|
indexToVerify--; |
2558 |
|
} |
2559 |
|
|
2560 |
|
/* verify the user selected index will exist */ |
2561 |
|
if (findEntryByIndex(config, indexToVerify)) { |
2562 |
config->defaultImage = newDefaultBootEntryIndex; |
config->defaultImage = newDefaultBootEntryIndex; |
2563 |
else |
} else { |
2564 |
config->defaultImage = NO_DEFAULT_ENTRY; |
config->defaultImage = NO_DEFAULT_ENTRY; |
2565 |
|
} |
2566 |
|
|
2567 |
return; |
return; |
2568 |
} else if (defaultKernelPath) { |
} |
2569 |
i = 0; |
|
2570 |
if (findEntryByPath(config, defaultKernelPath, prefix, &i)) { |
/* handle cases where the index value may shift */ |
2571 |
config->defaultImage = i; |
|
2572 |
} else { |
/* check validity of existing default or first-entry-found |
2573 |
|
selection */ |
2574 |
|
if (defaultKernelPath) { |
2575 |
|
/* we must initialize this */ |
2576 |
|
firstKernelEntryIndex = 0; |
2577 |
|
/* user requested first-entry-found */ |
2578 |
|
if (!findEntryByPath(config, defaultKernelPath, |
2579 |
|
prefix, &firstKernelEntryIndex)) { |
2580 |
|
/* don't change default if can't find match */ |
2581 |
config->defaultImage = NO_DEFAULT_ENTRY; |
config->defaultImage = NO_DEFAULT_ENTRY; |
2582 |
return; |
return; |
2583 |
} |
} |
|
} |
|
2584 |
|
|
2585 |
/* defaultImage now points to what we'd like to use, but before any |
config->defaultImage = firstKernelEntryIndex; |
|
* order changes */ |
|
|
if ((config->defaultImage == DEFAULT_SAVED) || |
|
|
(config->defaultImage == DEFAULT_SAVED_GRUB2)) |
|
|
/* default is set to saved, we don't want to change it */ |
|
|
return; |
|
2586 |
|
|
2587 |
if (config->defaultImage >= FIRST_ENTRY_INDEX) |
/* this is where we start looking for decrement later */ |
2588 |
entry = findEntryByIndex(config, config->defaultImage); |
currentLookupIndex = config->defaultImage; |
|
else |
|
|
entry = NULL; |
|
2589 |
|
|
2590 |
if (entry && !entry->skip) { |
if (isAddingBootEntry && !config->isModified && |
2591 |
/* we can preserve the default */ |
(newBootEntryIndex < config->defaultImage)) { |
2592 |
if (isUserSpecifiedKernelPath) |
/* increment because new entry added before default */ |
2593 |
config->defaultImage++; |
config->defaultImage++; |
|
|
|
|
/* count the number of entries erased before this one */ |
|
|
for (j = 0; j < config->defaultImage; j++) { |
|
|
entry2 = findEntryByIndex(config, j); |
|
|
if (entry2->skip) |
|
|
config->defaultImage--; |
|
2594 |
} |
} |
|
} else if (isUserSpecifiedKernelPath) { |
|
|
config->defaultImage = FIRST_ENTRY_INDEX; |
|
2595 |
} else { |
} else { |
2596 |
/* Either we just erased the default (or the default line was |
/* check to see if the default is stored in the environment */ |
2597 |
* bad to begin with) and didn't put a new one in. We'll use |
if (config->defaultImage < FIRST_ENTRY_INDEX) { |
2598 |
* the first valid image. */ |
if (config->defaultImage == DEFAULT_SAVED || config->defaultImage == DEFAULT_SAVED_GRUB2) |
2599 |
|
{ |
2600 |
|
if (config->cfi->defaultIsSaved) { |
2601 |
|
if (config->cfi->getEnv) { |
2602 |
|
char *defaultTitle = config->cfi->getEnv(config->cfi, "saved_entry"); |
2603 |
|
|
2604 |
|
if (defaultTitle) { |
2605 |
|
if (isnumber(defaultTitle)) { |
2606 |
|
currentLookupIndex = atoi(defaultTitle); |
2607 |
|
} else { |
2608 |
|
findEntryByTitle(config, defaultTitle, ¤tLookupIndex); |
2609 |
|
} |
2610 |
|
/* set the default Image to an actual index */ |
2611 |
|
config->defaultImage = currentLookupIndex; |
2612 |
|
} |
2613 |
|
} |
2614 |
|
} |
2615 |
|
} |
2616 |
|
} else { |
2617 |
|
/* use pre-existing default entry from the file*/ |
2618 |
|
currentLookupIndex = config->defaultImage; |
2619 |
|
} |
2620 |
|
|
2621 |
|
if (isAddingBootEntry |
2622 |
|
&& (newBootEntryIndex <= config->defaultImage)) { |
2623 |
|
config->defaultImage++; |
2624 |
|
|
2625 |
|
if (config->isModified) { |
2626 |
|
currentLookupIndex++; |
2627 |
|
} |
2628 |
|
} |
2629 |
|
} |
2630 |
|
|
2631 |
|
/* sanity check - is this entry index valid? */ |
2632 |
|
bootEntry = findEntryByIndex(config, currentLookupIndex); |
2633 |
|
|
2634 |
|
if ((bootEntry && bootEntry->skip) || !bootEntry) { |
2635 |
|
/* entry is to be skipped or is invalid */ |
2636 |
|
if (isAddingBootEntry) { |
2637 |
|
config->defaultImage = newBootEntryIndex; |
2638 |
|
return; |
2639 |
|
} |
2640 |
newDefault = |
newDefault = |
2641 |
findTemplate(config, prefix, &config->defaultImage, 1, |
findTemplate(config, prefix, &config->defaultImage, 1, |
2642 |
flags); |
flags); |
2643 |
if (!newDefault) |
if (!newDefault) { |
2644 |
config->defaultImage = NO_DEFAULT_ENTRY; |
config->defaultImage = NO_DEFAULT_ENTRY; |
2645 |
|
} |
2646 |
|
|
2647 |
|
return; |
2648 |
|
} |
2649 |
|
|
2650 |
|
currentLookupIndex--; |
2651 |
|
|
2652 |
|
/* decrement index by the total number of entries deleted */ |
2653 |
|
|
2654 |
|
for (indexToVerify = currentLookupIndex; |
2655 |
|
indexToVerify >= FIRST_ENTRY_INDEX; indexToVerify--) { |
2656 |
|
|
2657 |
|
bootEntry = findEntryByIndex(config, indexToVerify); |
2658 |
|
|
2659 |
|
if (bootEntry && bootEntry->skip) { |
2660 |
|
config->defaultImage--; |
2661 |
|
} |
2662 |
} |
} |
2663 |
} |
} |
2664 |
|
|
2687 |
} |
} |
2688 |
} |
} |
2689 |
|
|
2690 |
void displayEntry(struct singleEntry *entry, const char *prefix, int index) |
void displayEntry(struct grubConfig *config, struct singleEntry *entry, const char *prefix, int index) |
2691 |
{ |
{ |
2692 |
struct singleLine *line; |
struct singleLine *line; |
2693 |
char *root = NULL; |
char *root = NULL; |
2783 |
|
|
2784 |
line = getLineByType(LT_TITLE, entry->lines); |
line = getLineByType(LT_TITLE, entry->lines); |
2785 |
if (line) { |
if (line) { |
2786 |
printf("title=%s\n", line->elements[1].item); |
char *entryTitle; |
2787 |
|
/* if we can extractTitle, then it's a zipl config and |
2788 |
|
* if not then we go ahead with what's existed prior */ |
2789 |
|
entryTitle = extractTitle(config, line); |
2790 |
|
if (!entryTitle) { |
2791 |
|
entryTitle=line->elements[1].item; |
2792 |
|
} |
2793 |
|
printf("title=%s\n", entryTitle); |
2794 |
} else { |
} else { |
2795 |
char *title; |
char *title; |
2796 |
line = getLineByType(LT_MENUENTRY, entry->lines); |
line = getLineByType(LT_MENUENTRY, entry->lines); |
3206 |
printf("lba\n"); |
printf("lba\n"); |
3207 |
} |
} |
3208 |
|
|
3209 |
displayEntry(entry, prefix, i); |
displayEntry(config, entry, prefix, i); |
3210 |
|
|
3211 |
i++; |
i++; |
3212 |
while ((entry = findEntryByPath(config, kernel, prefix, &i))) { |
while ((entry = findEntryByPath(config, kernel, prefix, &i))) { |
3213 |
displayEntry(entry, prefix, i); |
displayEntry(config, entry, prefix, i); |
3214 |
i++; |
i++; |
3215 |
} |
} |
3216 |
|
|
4837 |
} |
} |
4838 |
|
|
4839 |
if (updateImage(config, indexs, prefix, newKernelArgs, NULL, |
if (updateImage(config, indexs, prefix, newKernelArgs, NULL, |
4840 |
newMBKernelArgs, NULL)) |
newMBKernelArgs, NULL)) { |
4841 |
|
config->isModified = 1; |
4842 |
return 1; |
return 1; |
4843 |
|
} |
4844 |
|
|
4845 |
return 0; |
return 0; |
4846 |
} |
} |
5373 |
markRemovedImage(config, removeKernelPath, bootPrefix); |
markRemovedImage(config, removeKernelPath, bootPrefix); |
5374 |
markRemovedImage(config, removeMBKernel, bootPrefix); |
markRemovedImage(config, removeMBKernel, bootPrefix); |
5375 |
setDefaultImage(config, newKernelPath != NULL, defaultKernel, |
setDefaultImage(config, newKernelPath != NULL, defaultKernel, |
5376 |
makeDefault, bootPrefix, flags, defaultIndex); |
makeDefault, bootPrefix, flags, defaultIndex, |
5377 |
|
newIndex); |
5378 |
setFallbackImage(config, newKernelPath != NULL); |
setFallbackImage(config, newKernelPath != NULL); |
5379 |
if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs, |
if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs, |
5380 |
removeArgs, newMBKernelArgs, removeMBKernelArgs)) |
removeArgs, newMBKernelArgs, removeMBKernelArgs)) |