--- trunk/grubby/grubby.c 2012/04/16 17:46:40 1800 +++ trunk/grubby/grubby.c 2012/07/02 12:59:07 1844 @@ -731,6 +731,18 @@ if (fprintf(out, "%s", line->indent) == -1) return -1; 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(out, "\'%s\'", line->elements[i].item); + else + fprintf(out, "%s", line->elements[i].item); + fprintf(out, "%s", line->elements[i].indent); + + continue; + } + if (i == 1 && line->type == LT_KERNELARGS && cfi->argsInQuotes) if (fputc('"', out) == EOF) return -1; @@ -889,13 +901,11 @@ break; } - free(line->elements[i].indent); + line->elements[i + 1].indent = line->elements[i].indent; line->elements[i].indent = strdup(indent); *p++ = '\0'; i++; line->elements[i].item = strdup(p); - line->elements[i].indent = strdup(""); - p = line->elements[i].item; } } } @@ -983,7 +993,7 @@ dbgPrintf("found 'set' command (%d elements): ", line->numElements); dbgPrintf("%s", line->indent); for (i = 0; i < line->numElements; i++) - dbgPrintf("%s\"%s\"", line->elements[i].indent, line->elements[i].item); + dbgPrintf("\"%s\"%s", line->elements[i].item, line->elements[i].indent); dbgPrintf("\n"); struct keywordTypes *kwType = getKeywordByType(LT_DEFAULT, cfi); if (kwType && line->numElements == 3 && @@ -1052,7 +1062,71 @@ line->elements[line->numElements - 1].indent; line->elements[1].item = buf; line->numElements = 2; + } else if (line->type == LT_MENUENTRY && line->numElements > 3) { + /* let --remove-kernel="TITLE=what" work */ + len = 0; + char *extras; + char *title; + + for (i = 1; i < line->numElements; i++) { + len += strlen(line->elements[i].item); + len += strlen(line->elements[i].indent); + } + buf = malloc(len + 1); + *buf = '\0'; + + /* allocate mem for extra flags. */ + extras = malloc(len + 1); + *extras = '\0'; + + /* get title. */ + for (i = 0; i < line->numElements; i++) { + if (!strcmp(line->elements[i].item, "menuentry")) + continue; + if (isquote(*line->elements[i].item)) + title = line->elements[i].item + 1; + else + title = line->elements[i].item; + + len = strlen(title); + if (isquote(title[len-1])) { + strncat(buf, title,len-1); + break; + } else { + strcat(buf, title); + strcat(buf, line->elements[i].indent); + } + } + + /* get extras */ + int count = 0; + for (i = 0; i < line->numElements; i++) { + if (count >= 2) { + strcat(extras, line->elements[i].item); + strcat(extras, line->elements[i].indent); + } + + if (!strcmp(line->elements[i].item, "menuentry")) + continue; + + /* count ' or ", there should be two in menuentry line. */ + if (isquote(*line->elements[i].item)) + count++; + + len = strlen(line->elements[i].item); + + if (isquote(line->elements[i].item[len -1])) + count++; + /* ok, we get the final ' or ", others are extras. */ + } + line->elements[1].indent = + line->elements[line->numElements - 2].indent; + line->elements[1].item = buf; + line->elements[2].indent = + line->elements[line->numElements - 2].indent; + line->elements[2].item = extras; + line->numElements = 3; } else if (line->type == LT_KERNELARGS && cfi->argsInQuotes) { /* Strip off any " which may be present; they'll be put back on write. This is one of the few (the only?) places that grubby @@ -1061,13 +1135,13 @@ if (line->numElements >= 2) { int last, len; - if (*line->elements[1].item == '"') + if (isquote(*line->elements[1].item)) memmove(line->elements[1].item, line->elements[1].item + 1, strlen(line->elements[1].item + 1) + 1); last = line->numElements - 1; len = strlen(line->elements[last].item) - 1; - if (line->elements[last].item[len] == '"') + if (isquote(line->elements[last].item[len])) line->elements[last].item[len] = '\0'; } } @@ -1387,6 +1461,8 @@ buf[rc] = '\0'; chptr = buf; + char *foundanswer = NULL; + while (chptr && chptr != buf+rc) { devname = chptr; @@ -1414,13 +1490,8 @@ * for '/' obviously. */ if (*(++chptr) == '/' && *(++chptr) == ' ') { - /* - * Move back 2, which is the first space after the device name, set - * it to \0 so strdup will just get the devicename. - */ - chptr -= 2; - *chptr = '\0'; - return strdup(devname); + /* remember the last / entry in mtab */ + foundanswer = devname; } /* Next line */ @@ -1429,6 +1500,13 @@ chptr++; } + /* Return the last / entry found */ + if (foundanswer) { + chptr = strchr(foundanswer, ' '); + *chptr = '\0'; + return strdup(foundanswer); + } + return NULL; } @@ -1439,7 +1517,19 @@ for (line = entry->lines; line; line = line->next) { fprintf(stderr, "DBG: %s", line->indent); for (i = 0; i < line->numElements; i++) { - fprintf(stderr, "%s%s", + /* 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); + else + fprintf(stderr, "%s", line->elements[i].item); + fprintf(stderr, "%s", line->elements[i].indent); + + continue; + } + + fprintf(stderr, "%s%s", line->elements[i].item, line->elements[i].indent); } fprintf(stderr, "\n"); @@ -1655,7 +1745,7 @@ if (!strncmp(kernel, "TITLE=", 6)) { prefix = ""; - checkType = LT_TITLE; + checkType = LT_TITLE|LT_MENUENTRY; kernel += 6; } @@ -1671,13 +1761,17 @@ checkType, line); if (!line) break; /* not found in this entry */ - if (line && line->numElements >= 2) { + if (line && line->type != LT_MENUENTRY && + line->numElements >= 2) { rootspec = getRootSpecifier(line->elements[1].item); if (!strcmp(line->elements[1].item + ((rootspec != NULL) ? strlen(rootspec) : 0), kernel + strlen(prefix))) break; } + if(line->type == LT_MENUENTRY && + !strcmp(line->elements[1].item, kernel)) + break; } /* make sure this entry has a kernel identifier; this skips @@ -1769,7 +1863,16 @@ const char * prefix) { struct singleEntry * entry; - if (!image) return; + if (!image) + return; + + /* check and see if we're removing the default image */ + if (isdigit(*image)) { + entry = findEntryByPath(cfg, image, prefix, NULL); + if(entry) + entry->skip = 1; + return; + } while ((entry = findEntryByPath(cfg, image, prefix, NULL))) entry->skip = 1; @@ -2876,7 +2979,7 @@ static char * getInitrdVal(struct grubConfig * config, const char * prefix, struct singleLine *tmplLine, const char * newKernelInitrd, - char ** extraInitrds, int extraInitrdCount) + const char ** extraInitrds, int extraInitrdCount) { char *initrdVal, *end; int i; @@ -2921,10 +3024,10 @@ int addNewKernel(struct grubConfig * config, struct singleEntry * template, const char * prefix, - char * newKernelPath, char * newKernelTitle, - char * newKernelArgs, char * newKernelInitrd, - char ** extraInitrds, int extraInitrdCount, - char * newMBKernel, char * newMBKernelArgs) { + const char * newKernelPath, const char * newKernelTitle, + const char * newKernelArgs, const char * newKernelInitrd, + const char ** extraInitrds, int extraInitrdCount, + const char * newMBKernel, const char * newMBKernelArgs) { struct singleEntry * new; struct singleLine * newLine = NULL, * tmplLine = NULL, * masterLine = NULL; int needs; @@ -3486,20 +3589,20 @@ } if (!cfi) { + if (grub2FindConfig(&grub2ConfigType)) + cfi = &grub2ConfigType; + else #ifdef __ia64__ - cfi = &eliloConfigType; + cfi = &eliloConfigType; #elif __powerpc__ - cfi = &yabootConfigType; + cfi = &yabootConfigType; #elif __sparc__ - cfi = &siloConfigType; + cfi = &siloConfigType; #elif __s390__ - cfi = &ziplConfigType; + cfi = &ziplConfigType; #elif __s390x__ - cfi = &ziplConfigtype; + cfi = &ziplConfigtype; #else - if (grub2FindConfig(&grub2ConfigType)) - cfi = &grub2ConfigType; - else cfi = &grubConfigType; #endif } @@ -3710,7 +3813,7 @@ } if (addNewKernel(config, template, bootPrefix, newKernelPath, newKernelTitle, newKernelArgs, newKernelInitrd, - extraInitrds, extraInitrdCount, + (const char **)extraInitrds, extraInitrdCount, newMBKernel, newMBKernelArgs)) return 1;