--- trunk/grubby/grubby.c 2016/06/29 14:41:26 2963 +++ trunk/grubby/grubby.c 2016/06/30 10:32:12 2989 @@ -222,6 +222,7 @@ .mbHyperFirst = 1, .mbInitRdIsModule = 1, .mbAllowExtraInitRds = 1, + .titlePosition = 1, }; struct keywordTypes grub2Keywords[] = { @@ -451,6 +452,8 @@ * whose last character is also quote (assuming it's the closing one) */ int resultMaxSize; char * result; + /* need to ensure that ' does not match " as we search */ + char quote_char = *current; resultMaxSize = sizeOfSingleLine(line); result = malloc(resultMaxSize); @@ -464,7 +467,7 @@ current_indent_len = strlen(current_indent); strncat(result, current_indent, current_indent_len); - if (!isquote(current[current_len-1])) { + if (current[current_len-1] != quote_char) { strncat(result, current, current_len); } else { strncat(result, current, current_len - 1); @@ -582,6 +585,8 @@ { "initrd", LT_INITRD, ' ', ',' }, { "append", LT_KERNELARGS, ' ' }, { "prompt", LT_UNKNOWN, ' ' }, + { "fdt", LT_DEVTREE, ' ' }, + { "fdtdir", LT_DEVTREE, ' ' }, { NULL, 0, 0 }, }; int useextlinuxmenu; @@ -592,6 +597,7 @@ .needsBootPrefix = 1, .argsInQuotes = 1, .mbConcatArgs = 1, + .titlePosition = 1, }; struct configFileInfo liloConfigType = { @@ -600,6 +606,7 @@ .entryStart = LT_KERNEL, .argsInQuotes = 1, .maxTitleLength = 15, + .titlePosition = 1, }; struct configFileInfo yabootConfigType = { @@ -610,6 +617,7 @@ .argsInQuotes = 1, .maxTitleLength = 15, .mbAllowExtraInitRds = 1, + .titlePosition = 1, }; struct configFileInfo siloConfigType = { @@ -619,6 +627,7 @@ .needsBootPrefix = 1, .argsInQuotes = 1, .maxTitleLength = 15, + .titlePosition = 1, }; struct configFileInfo ziplConfigType = { @@ -638,6 +647,7 @@ .maxTitleLength = 255, .mbAllowExtraInitRds = 1, .defaultIsUnquoted = 1, + .titlePosition = 1, }; struct grubConfig { @@ -826,13 +836,18 @@ } /* extract the title from within brackets (for zipl) */ -static char * extractTitle(struct singleLine * line) { - /* bracketed title... let's extract it (leaks a byte) */ +static char * extractTitle(struct grubConfig *cfg, struct singleLine * line) { + /* bracketed title... let's extract it */ char * title = NULL; if (line->type == LT_TITLE) { - title = strdup(line->elements[0].item); - title++; - *(title + strlen(title) - 1) = '\0'; + char *tmp = line->elements[cfg->cfi->titlePosition].item; + if (cfg->cfi->titleBracketed) { + tmp++; + title = strdup(tmp); + *(title + strlen(title) - 1) = '\0'; + } else { + title = strdup(tmp); + } } else if (line->type == LT_MENUENTRY) title = strdup(line->elements[1].item); else @@ -916,10 +931,23 @@ /* Need to handle this, because we strip the quotes from * menuentry when read it. */ if (line->type == LT_MENUENTRY && i == 1) { - if(!isquote(*line->elements[i].item)) - fprintf(out, "\'%s\'", line->elements[i].item); - else + if(!isquote(*line->elements[i].item)) { + int substring = 0; + /* If the line contains nested quotes, we did not strip + * the "interna" quotes and we must use the right quotes + * again when writing the updated file. */ + for (int j = i; j < line->numElements; j++) { + if (strchr(line->elements[i].item, '\'') != NULL) { + substring = 1; + fprintf(out, "\"%s\"", line->elements[i].item); + break; + } + } + if (!substring) + fprintf(out, "\'%s\'", line->elements[i].item); + } else { fprintf(out, "%s", line->elements[i].item); + } fprintf(out, "%s", line->elements[i].indent); continue; @@ -1255,6 +1283,8 @@ len = 0; char *extras; char *title; + /* initially unseen value */ + char quote_char = '\0'; for (int i = 1; i < line->numElements; i++) { len += strlen(line->elements[i].item); @@ -1271,13 +1301,16 @@ for (int i = 0; i < line->numElements; i++) { if (!strcmp(line->elements[i].item, "menuentry")) continue; - if (isquote(*line->elements[i].item)) + if (isquote(*line->elements[i].item) && quote_char == '\0') { + /* ensure we properly pair off quotes */ + quote_char = *line->elements[i].item; title = line->elements[i].item + 1; - else + } else { title = line->elements[i].item; + } len = strlen(title); - if (isquote(title[len-1])) { + if (title[len-1] == quote_char) { strncat(buf, title,len-1); break; } else { @@ -1288,6 +1321,7 @@ /* get extras */ int count = 0; + quote_char = '\0'; for (int i = 0; i < line->numElements; i++) { if (count >= 2) { strcat(extras, line->elements[i].item); @@ -1298,12 +1332,15 @@ continue; /* count ' or ", there should be two in menuentry line. */ - if (isquote(*line->elements[i].item)) + if (isquote(*line->elements[i].item) && quote_char == '\0') { + /* ensure we properly pair off quotes */ + quote_char = *line->elements[i].item; count++; + } len = strlen(line->elements[i].item); - if (isquote(line->elements[i].item[len -1])) + if (line->elements[i].item[len -1] == quote_char) count++; /* ok, we get the final ' or ", others are extras. */ @@ -1440,7 +1477,7 @@ line->elements[1].item)) break; } else if (line) { if (!strcmp(defaultLine->elements[1].item, - extractTitle(line))) break; + extractTitle(cfg, line))) break; } i++; entry = NULL; @@ -1491,7 +1528,7 @@ if (!line) line = getLineByType(LT_TITLE, entry->lines); if (line) { - title = extractTitle(line); + title = extractTitle(cfg, line); if (title) cfg->cfi->setEnv(cfg->cfi, "saved_entry", title); } @@ -1529,7 +1566,7 @@ else if (line && (line->numElements == 1) && cfg->cfi->titleBracketed) { fprintf(out, "%sdefault%s%s\n", indent, separator, - extractTitle(line)); + extractTitle(cfg, line)); } } } @@ -3331,7 +3368,7 @@ if (!line) continue; - linetitle = extractTitle(line); + linetitle = extractTitle(cfg, line); if (!linetitle) continue; if (strcmp(title, linetitle)) { @@ -3385,7 +3422,7 @@ if (!line) continue; - linetitle = extractTitle(line); + linetitle = extractTitle(cfg, line); if (!linetitle) continue; if (strcmp(title, linetitle)) { @@ -4269,6 +4306,8 @@ _("display the title of the default kernel") }, { "devtree", 0, POPT_ARG_STRING, &newDevTreePath, 0, _("device tree file for new stanza"), _("dtb-path") }, + { "devtreedir", 0, POPT_ARG_STRING, &newDevTreePath, 0, + _("device tree directory for new stanza"), _("dtb-path") }, { "elilo", 0, POPT_ARG_NONE, &configureELilo, 0, _("configure elilo bootloader") }, { "efi", 0, POPT_ARG_NONE, &isEfi, 0, @@ -4409,9 +4448,11 @@ } if (!cfi) { - if (grub2FindConfig(&grub2ConfigType)) + if (grub2FindConfig(&grub2ConfigType)) { cfi = &grub2ConfigType; - else + if (envPath) + cfi->envFile = envPath; + } else #ifdef __ia64__ cfi = &eliloConfigType; #elif __powerpc__