--- trunk/grubby/grubby.c 2012/10/01 12:39:50 1940 +++ trunk/grubby/grubby.c 2013/10/21 13:19:07 2236 @@ -36,6 +36,8 @@ #include #include +#include "log.h" + #ifndef DEBUG #define DEBUG 0 #endif @@ -58,6 +60,8 @@ int isEfi = 0; +char *saved_command_line = NULL; + /* comments get lumped in with indention */ struct lineElement { char * item; @@ -138,6 +142,7 @@ findConfigFunc findConfig; writeLineFunc writeLine; struct keywordTypes * keywords; + int caseInsensitive; int defaultIsIndex; int defaultIsVariable; int defaultSupportSaved; @@ -496,6 +501,7 @@ struct configFileInfo extlinuxConfigType = { .defaultConfig = "/boot/extlinux/extlinux.conf", .keywords = extlinuxKeywords, + .caseInsensitive = 1, .entryStart = LT_TITLE, .needsBootPrefix = 1, .maxTitleLength = 255, @@ -632,8 +638,13 @@ static enum lineType_e getTypeByKeyword(char * keyword, struct configFileInfo * cfi) { for (struct keywordTypes *kw = cfi->keywords; kw->key; kw++) { - if (!strcmp(keyword, kw->key)) - return kw->type; + if (cfi->caseInsensitive) { + if (!strcasecmp(keyword, kw->key)) + return kw->type; + } else { + if (!strcmp(keyword, kw->key)) + return kw->type; + } } return LT_UNKNOWN; } @@ -1527,43 +1538,67 @@ return NULL; } -void printEntry(struct singleEntry * entry) { +void printEntry(struct singleEntry * entry, FILE *f) { int i; struct singleLine * line; for (line = entry->lines; line; line = line->next) { - fprintf(stderr, "DBG: %s", line->indent); + log_message(f, "DBG: %s", line->indent); for (i = 0; i < line->numElements; i++) { /* 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(stderr, "\'%s\'", line->elements[i].item); + log_message(f, "\'%s\'", line->elements[i].item); else - fprintf(stderr, "%s", line->elements[i].item); - fprintf(stderr, "%s", line->elements[i].indent); + log_message(f, "%s", line->elements[i].item); + log_message(f, "%s", line->elements[i].indent); continue; } - fprintf(stderr, "%s%s", + log_message(f, "%s%s", line->elements[i].item, line->elements[i].indent); } - fprintf(stderr, "\n"); + log_message(f, "\n"); } } -void notSuitablePrintf(struct singleEntry * entry, const char *fmt, ...) +void notSuitablePrintf(struct singleEntry * entry, int okay, const char *fmt, ...) { - va_list argp; + static int once; + va_list argp, argq; + + va_start(argp, fmt); - if (!debug) + va_copy(argq, argp); + if (!once) { + log_time(NULL); + log_message(NULL, "command line: %s\n", saved_command_line); + } + log_message(NULL, "DBG: Image entry %s: ", okay ? "succeeded" : "failed"); + log_vmessage(NULL, fmt, argq); + + printEntry(entry, NULL); + va_end(argq); + + if (!debug) { + once = 1; + va_end(argp); return; + } - va_start(argp, fmt); + if (okay) { + va_end(argp); + return; + } + + if (!once) + log_message(stderr, "DBG: command line: %s\n", saved_command_line); + once = 1; fprintf(stderr, "DBG: Image entry failed: "); vfprintf(stderr, fmt, argp); - printEntry(entry); + printEntry(entry, stderr); va_end(argp); } @@ -1590,22 +1625,25 @@ char * rootdev; if (skipRemoved && entry->skip) { - notSuitablePrintf(entry, "marked to skip\n"); + notSuitablePrintf(entry, 0, "marked to skip\n"); return 0; } line = getLineByType(LT_KERNEL|LT_HYPER|LT_KERNEL_EFI, entry->lines); if (!line) { - notSuitablePrintf(entry, "no line found\n"); + notSuitablePrintf(entry, 0, "no line found\n"); return 0; } if (line->numElements < 2) { - notSuitablePrintf(entry, "line has only %d elements\n", + notSuitablePrintf(entry, 0, "line has only %d elements\n", line->numElements); return 0; } - if (flags & GRUBBY_BADIMAGE_OKAY) return 1; + if (flags & GRUBBY_BADIMAGE_OKAY) { + notSuitablePrintf(entry, 1, "\n"); + return 1; + } fullName = alloca(strlen(bootPrefix) + strlen(line->elements[1].item) + 1); @@ -1616,7 +1654,7 @@ sprintf(fullName, "%s%s%s", bootPrefix, hasslash ? "" : "/", line->elements[1].item + rootspec_offset); if (access(fullName, R_OK)) { - notSuitablePrintf(entry, "access to %s failed\n", fullName); + notSuitablePrintf(entry, 0, "access to %s failed\n", fullName); return 0; } for (i = 2; i < line->numElements; i++) @@ -1637,7 +1675,7 @@ /* failed to find one */ if (!line) { - notSuitablePrintf(entry, "no line found\n"); + notSuitablePrintf(entry, 0, "no line found\n"); return 0; } @@ -1646,7 +1684,7 @@ if (i < line->numElements) dev = line->elements[i].item + 5; else { - notSuitablePrintf(entry, "no root= entry found\n"); + notSuitablePrintf(entry, 0, "no root= entry found\n"); /* it failed too... can't find root= */ return 0; } @@ -1655,32 +1693,33 @@ dev = getpathbyspec(dev); if (!getpathbyspec(dev)) { - notSuitablePrintf(entry, "can't find blkid entry for %s\n", dev); + notSuitablePrintf(entry, 0, "can't find blkid entry for %s\n", dev); return 0; } else dev = getpathbyspec(dev); rootdev = findDiskForRoot(); if (!rootdev) { - notSuitablePrintf(entry, "can't find root device\n"); + notSuitablePrintf(entry, 0, "can't find root device\n"); return 0; } if (!getuuidbydev(rootdev) || !getuuidbydev(dev)) { - notSuitablePrintf(entry, "uuid missing: rootdev %s, dev %s\n", + notSuitablePrintf(entry, 0, "uuid missing: rootdev %s, dev %s\n", getuuidbydev(rootdev), getuuidbydev(dev)); free(rootdev); return 0; } if (strcmp(getuuidbydev(rootdev), getuuidbydev(dev))) { - notSuitablePrintf(entry, "uuid mismatch: rootdev %s, dev %s\n", + notSuitablePrintf(entry, 0, "uuid mismatch: rootdev %s, dev %s\n", getuuidbydev(rootdev), getuuidbydev(dev)); free(rootdev); return 0; } free(rootdev); + notSuitablePrintf(entry, 1, "\n"); return 1; } @@ -1773,10 +1812,14 @@ /* check all the lines matching checkType */ for (line = entry->lines; line; line = line->next) { - line = getLineByType(entry->multiboot && checkType == LT_KERNEL - ? LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER - : checkType, line); - if (!line) break; /* not found in this entry */ + enum lineType_e ct = checkType; + if (entry->multiboot && checkType == LT_KERNEL) + ct = LT_KERNEL|LT_KERNEL_EFI|LT_MBMODULE|LT_HYPER; + else if (checkType & LT_KERNEL) + ct = checkType | LT_KERNEL_EFI; + line = getLineByType(ct, line); + if (!line) + break; /* not found in this entry */ if (line && line->type != LT_MENUENTRY && line->numElements >= 2) { @@ -3746,7 +3789,7 @@ memset(array, '\0', sizeof (array)); size = backtrace(array, 40); - fprintf(stderr, "grubby recieved SIGSEGV! Backtrace (%ld):\n", + fprintf(stderr, "grubby received SIGSEGV! Backtrace (%ld):\n", (unsigned long)size); backtrace_symbols_fd(array, size, STDERR_FILENO); exit(1); @@ -3844,7 +3887,7 @@ { "initrd", 0, POPT_ARG_STRING, &newKernelInitrd, 0, _("initrd image for the new kernel"), _("initrd-path") }, { "extra-initrd", 'i', POPT_ARG_STRING, NULL, 'i', - _("auxilliary initrd image for things other than the new kernel"), _("initrd-path") }, + _("auxiliary initrd image for things other than the new kernel"), _("initrd-path") }, { "lilo", 0, POPT_ARG_NONE, &configureLilo, 0, _("configure lilo bootloader") }, { "make-default", 0, 0, &makeDefault, 0, @@ -3888,6 +3931,20 @@ signal(SIGSEGV, traceback); + int i = 0; + for (int j = 1; j < argc; j++) + i += strlen(argv[j]) + 1; + saved_command_line = malloc(i); + if (!saved_command_line) { + fprintf(stderr, "grubby: %m\n"); + exit(1); + } + saved_command_line[0] = '\0'; + for (int j = 1; j < argc; j++) { + strcat(saved_command_line, argv[j]); + strncat(saved_command_line, j == argc -1 ? "" : " ", 1); + } + optCon = poptGetContext("grubby", argc, argv, options, 0); poptReadDefaultConfig(optCon, 1);