--- trunk/grubby/grubby.c 2012/02/18 01:05:52 1745 +++ trunk/grubby/grubby.c 2012/02/18 01:09:51 1750 @@ -114,6 +114,7 @@ #define MAIN_DEFAULT (1 << 0) #define DEFAULT_SAVED -2 +#define DEFAULT_SAVED_GRUB2 -3 struct keywordTypes { char * key; @@ -241,11 +242,94 @@ return configFiles[i]; } +int sizeOfSingleLine(struct singleLine * line) { + int i; + int count = 0; + + for (i = 0; i < line->numElements; i++) { + int indentSize = 0; + + count = count + strlen(line->elements[i].item); + + indentSize = strlen(line->elements[i].indent); + if (indentSize > 0) + count = count + indentSize; + else + /* be extra safe and add room for whitespaces */ + count = count + 1; + } + + /* room for trailing terminator */ + count = count + 1; + + return count; +} + +char *grub2ExtractTitle(struct singleLine * line) { + char * current; + char * current_indent; + int current_len; + int current_indent_len; + int i; + + /* bail out if line does not start with menuentry */ + if (strcmp(line->elements[0].item, "menuentry")) + return NULL; + + i = 1; + current = line->elements[i].item; + current_len = strlen(current); + + /* if second word is quoted, strip the quotes and return single word */ + if ((*current == '\'') && (*(current + current_len - 1) == '\'')) { + char *tmp; + + tmp = strdup(current); + *(tmp + current_len - 1) = '\0'; + return ++tmp; + } + + /* if no quotes, return second word verbatim */ + if (*current != '\'') { + return current; + } + + /* second element start with a quote, so we have to find the element + * whose last character is also quote (assuming it's the closing one) */ + if (*current == '\'') { + int resultMaxSize; + char * result; + + resultMaxSize = sizeOfSingleLine(line); + result = malloc(resultMaxSize); + snprintf(result, resultMaxSize, "%s", ++current); + + i++; + for (; i < line->numElements; ++i) { + current = line->elements[i].item; + current_len = strlen(current); + current_indent = line->elements[i].indent; + current_indent_len = strlen(current_indent); + + strncat(result, current_indent, current_indent_len); + if (*(current + current_len - 1) != '\'') { + strncat(result, current, current_len); + } else { + strncat(result, current, current_len - 1); + break; + } + } + return result; + } + + return NULL; +} + struct configFileInfo grub2ConfigType = { .findConfig = grub2FindConfig, .keywords = grub2Keywords, .defaultIsIndex = 1, - .defaultSupportSaved = 0, + .defaultSupportSaved = 1, .defaultIsVariable = 1, .entryStart = LT_MENUENTRY, .entryEnd = LT_ENTRY_END, @@ -1040,7 +1124,11 @@ dbgPrintf("defaultLine is %s\n", defaultLine ? "set" : "unset"); if (defaultLine) { - if (cfi->defaultIsVariable) { + if (defaultLine->numElements > 2 && + cfi->defaultSupportSaved && + !strncmp(defaultLine->elements[2].item,"\"${saved_entry}\"", 16)) { + cfg->defaultImage = DEFAULT_SAVED_GRUB2; + } else if (cfi->defaultIsVariable) { char *value = defaultLine->elements[2].item; while (*value && (*value == '"' || *value == '\'' || *value == ' ' || *value == '\t')) @@ -1097,6 +1185,8 @@ if (cfg->defaultImage == DEFAULT_SAVED) fprintf(out, "%sdefault%ssaved\n", indent, separator); + else if (cfg->defaultImage == DEFAULT_SAVED_GRUB2) + fprintf(out, "%sset default=\"${saved_entry}\"\n", indent); else if (cfg->defaultImage > -1) { if (cfg->cfi->defaultIsIndex) { if (cfg->cfi->defaultIsVariable) { @@ -1374,7 +1464,7 @@ { int slen; - if (!s && !s[0]) + if (!s || !s[0]) return 0; slen = strlen(s) - 1; @@ -1704,7 +1794,8 @@ /* defaultImage now points to what we'd like to use, but before any order changes */ - if (config->defaultImage == DEFAULT_SAVED) + if ((config->defaultImage == DEFAULT_SAVED) || + (config->defaultImage == DEFAULT_SAVED_GRUB2)) /* default is set to saved, we don't want to change it */ return; @@ -1771,7 +1862,7 @@ return; } - printf("kernel=%s\n", line->elements[1].item); + printf("kernel=%s%s\n", prefix, line->elements[1].item); if (line->numElements >= 3) { printf("args=\""); @@ -3577,37 +3668,14 @@ printf("%s\n", line->elements[1].item); } else { - int i; - size_t len; - char * start; - char * tmp; + char * title; dbgPrintf("This is GRUB2, default title is embeded in menuentry\n"); line = getLineByType(LT_MENUENTRY, entry->lines); if (!line) return 0; - - for (i = 0; i < line->numElements; i++) { - - if (!strcmp(line->elements[i].item, "menuentry")) - continue; - - if (*line->elements[i].item == '\'') - start = line->elements[i].item + 1; - else - start = line->elements[i].item; - - len = strlen(start); - if (*(start + len - 1) == '\'') { - tmp = strdup(start); - *(tmp + len - 1) = '\0'; - printf("%s", tmp); - free(tmp); - break; - } else { - printf("%s ", start); - } - } - printf("\n"); + title = grub2ExtractTitle(line); + if (title) + printf("%s\n", title); } return 0;