75 |
}; |
}; |
76 |
|
|
77 |
enum lineType_e { |
enum lineType_e { |
78 |
|
LT_UNIDENTIFIED = 0, |
79 |
LT_WHITESPACE = 1 << 0, |
LT_WHITESPACE = 1 << 0, |
80 |
LT_TITLE = 1 << 1, |
LT_TITLE = 1 << 1, |
81 |
LT_KERNEL = 1 << 2, |
LT_KERNEL = 1 << 2, |
751 |
return buf; |
return buf; |
752 |
} |
} |
753 |
|
|
754 |
|
static inline int |
755 |
|
kwcmp(struct keywordTypes *kw, const char * label, int case_insensitive) |
756 |
|
{ |
757 |
|
int kwl = strlen(kw->key); |
758 |
|
int ll = strlen(label); |
759 |
|
int rc; |
760 |
|
int (*snc)(const char *s1, const char *s2, size_t n) = |
761 |
|
case_insensitive ? strncasecmp : strncmp; |
762 |
|
int (*sc)(const char *s1, const char *s2) = |
763 |
|
case_insensitive ? strcasecmp : strcmp; |
764 |
|
|
765 |
|
rc = snc(kw->key, label, kwl); |
766 |
|
if (rc) |
767 |
|
return rc; |
768 |
|
|
769 |
|
for (int i = kwl; i < ll; i++) { |
770 |
|
if (isspace(label[i])) |
771 |
|
return 0; |
772 |
|
if (kw->separatorChar && label[i] == kw->separatorChar) |
773 |
|
return 0; |
774 |
|
else if (kw->nextChar && label[i] == kw->nextChar) |
775 |
|
return 0; |
776 |
|
return sc(kw->key+kwl, label+kwl); |
777 |
|
} |
778 |
|
return 0; |
779 |
|
} |
780 |
|
|
781 |
static enum lineType_e preferredLineType(enum lineType_e type, |
static enum lineType_e preferredLineType(enum lineType_e type, |
782 |
struct configFileInfo *cfi) |
struct configFileInfo *cfi) |
783 |
{ |
{ |
843 |
struct configFileInfo *cfi) |
struct configFileInfo *cfi) |
844 |
{ |
{ |
845 |
for (struct keywordTypes * kw = cfi->keywords; kw->key; kw++) { |
for (struct keywordTypes * kw = cfi->keywords; kw->key; kw++) { |
846 |
if (cfi->caseInsensitive) { |
if (!kwcmp(kw, keyword, cfi->caseInsensitive)) |
847 |
if (!strcasecmp(keyword, kw->key)) |
return kw->type; |
|
return kw->type; |
|
|
} else { |
|
|
if (!strcmp(keyword, kw->key)) |
|
|
return kw->type; |
|
|
} |
|
848 |
} |
} |
849 |
return LT_UNKNOWN; |
return LT_UNKNOWN; |
850 |
} |
} |
939 |
|
|
940 |
static void lineInit(struct singleLine *line) |
static void lineInit(struct singleLine *line) |
941 |
{ |
{ |
942 |
|
line->type = LT_UNIDENTIFIED; |
943 |
line->indent = NULL; |
line->indent = NULL; |
944 |
line->elements = NULL; |
line->elements = NULL; |
945 |
line->numElements = 0; |
line->numElements = 0; |
1022 |
|
|
1023 |
if (fprintf(out, "%s", line->elements[i].item) == -1) |
if (fprintf(out, "%s", line->elements[i].item) == -1) |
1024 |
return -1; |
return -1; |
1025 |
if (i < line->numElements - 1) |
if (i < line->numElements - 1 || line->type == LT_SET_VARIABLE) |
1026 |
if (fprintf(out, "%s", line->elements[i].indent) == -1) |
if (fprintf(out, "%s", line->elements[i].indent) == -1) |
1027 |
return -1; |
return -1; |
1028 |
} |
} |
1077 |
break; |
break; |
1078 |
chptr++; |
chptr++; |
1079 |
} |
} |
1080 |
|
if (line->type == LT_UNIDENTIFIED) |
1081 |
|
line->type = getTypeByKeyword(start, cfi); |
1082 |
element->item = strndup(start, chptr - start); |
element->item = strndup(start, chptr - start); |
1083 |
start = chptr; |
start = chptr; |
1084 |
|
|
1144 |
line->type = LT_WHITESPACE; |
line->type = LT_WHITESPACE; |
1145 |
line->numElements = 0; |
line->numElements = 0; |
1146 |
} |
} |
1147 |
} else { |
} else if (line->type == LT_INITRD) { |
1148 |
struct keywordTypes *kw; |
struct keywordTypes *kw; |
1149 |
|
|
1150 |
kw = getKeywordByType(line->type, cfi); |
kw = getKeywordByType(line->type, cfi); |
1206 |
} |
} |
1207 |
} |
} |
1208 |
} |
} |
1209 |
|
} else if (line->type == LT_SET_VARIABLE) { |
1210 |
|
/* and if it's a "set blah=" we need to split it |
1211 |
|
* yet a third way to avoid rhbz# XXX FIXME :/ |
1212 |
|
*/ |
1213 |
|
char *eq; |
1214 |
|
int l; |
1215 |
|
int numElements = line->numElements; |
1216 |
|
struct lineElement *newElements; |
1217 |
|
eq = strchr(line->elements[1].item, '='); |
1218 |
|
if (!eq) |
1219 |
|
return 0; |
1220 |
|
l = eq - line->elements[1].item; |
1221 |
|
if (eq[1] != 0) |
1222 |
|
numElements++; |
1223 |
|
newElements = calloc(numElements,sizeof (*newElements)); |
1224 |
|
memcpy(&newElements[0], &line->elements[0], |
1225 |
|
sizeof (newElements[0])); |
1226 |
|
newElements[1].item = |
1227 |
|
strndup(line->elements[1].item, l); |
1228 |
|
newElements[1].indent = "="; |
1229 |
|
*(eq++) = '\0'; |
1230 |
|
newElements[2].item = strdup(eq); |
1231 |
|
free(line->elements[1].item); |
1232 |
|
if (line->elements[1].indent) |
1233 |
|
newElements[2].indent = line->elements[1].indent; |
1234 |
|
for (int i = 2; i < line->numElements; i++) { |
1235 |
|
newElements[i+1].item = line->elements[i].item; |
1236 |
|
newElements[i+1].indent = |
1237 |
|
line->elements[i].indent; |
1238 |
|
} |
1239 |
|
free(line->elements); |
1240 |
|
line->elements = newElements; |
1241 |
|
line->numElements = numElements; |
1242 |
} |
} |
1243 |
} |
} |
1244 |
|
|
1344 |
getKeywordByType(LT_DEFAULT, cfi); |
getKeywordByType(LT_DEFAULT, cfi); |
1345 |
if (kwType && line->numElements == 3 |
if (kwType && line->numElements == 3 |
1346 |
&& !strcmp(line->elements[1].item, kwType->key) |
&& !strcmp(line->elements[1].item, kwType->key) |
1347 |
&& !is_special_grub2_variable(line->elements[2]. |
&& !is_special_grub2_variable( |
1348 |
item)) { |
line->elements[2].item)) { |
1349 |
dbgPrintf("Line sets default config\n"); |
dbgPrintf("Line sets default config\n"); |
1350 |
cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT; |
cfg->flags &= ~GRUB_CONFIG_NO_DEFAULT; |
1351 |
defaultLine = line; |
defaultLine = line; |
1352 |
} |
} |
|
|
|
1353 |
} else if (iskernel(line->type)) { |
} else if (iskernel(line->type)) { |
1354 |
/* if by some freak chance this is multiboot and the |
/* if by some freak chance this is multiboot and the |
1355 |
* "module" lines came earlier in the template, make |
* "module" lines came earlier in the template, make |
1603 |
} |
} |
1604 |
} |
} |
1605 |
} else if (cfi->defaultIsVariable) { |
} else if (cfi->defaultIsVariable) { |
1606 |
char *value = defaultLine->elements[2].item; |
if (defaultLine->numElements == 2) { |
1607 |
while (*value && (*value == '"' || *value == '\'' || |
char *value = defaultLine->elements[1].item + 8; |
1608 |
*value == ' ' || *value == '\t')) |
while (*value && (*value == '"' || |
1609 |
value++; |
*value == '\'' || |
1610 |
cfg->defaultImage = strtol(value, &end, 10); |
*value == ' ' || |
1611 |
while (*end && (*end == '"' || *end == '\'' || |
*value == '\t')) |
1612 |
*end == ' ' || *end == '\t')) |
value++; |
1613 |
end++; |
cfg->defaultImage = strtol(value, &end, 10); |
1614 |
if (*end) |
while (*end && (*end == '"' || *end == '\'' || |
1615 |
cfg->defaultImage = -1; |
*end == ' ' || *end == '\t')) |
1616 |
|
end++; |
1617 |
|
if (*end) |
1618 |
|
cfg->defaultImage = -1; |
1619 |
|
} else if (defaultLine->numElements == 3) { |
1620 |
|
char *value = defaultLine->elements[2].item; |
1621 |
|
while (*value && (*value == '"' || |
1622 |
|
*value == '\'' || |
1623 |
|
*value == ' ' || |
1624 |
|
*value == '\t')) |
1625 |
|
value++; |
1626 |
|
cfg->defaultImage = strtol(value, &end, 10); |
1627 |
|
while (*end && (*end == '"' || *end == '\'' || |
1628 |
|
*end == ' ' || *end == '\t')) |
1629 |
|
end++; |
1630 |
|
if (*end) |
1631 |
|
cfg->defaultImage = -1; |
1632 |
|
} |
1633 |
} else if (cfi->defaultSupportSaved && |
} else if (cfi->defaultSupportSaved && |
1634 |
!strncmp(defaultLine->elements[1].item, "saved", |
!strncmp(defaultLine->elements[1].item, "saved", |
1635 |
5)) { |
5)) { |