in lsvmutils/grubcfg.c [526:690]
static int _ResolveInitrd(
const GRUBCommand* commands,
UINTN numCommands,
char matched[PATH_MAX],
char title[PATH_MAX],
char path[PATH_MAX])
{
int rc = -1;
UINTN i;
const char* defaultValue = NULL;
StrArr arr = STRARR_INITIALIZER;
const UINTN STACK_SIZE = 16;
Element stack[STACK_SIZE];
UINT32 top = 0;
BOOLEAN hasDefault = TRUE;
if (path)
*path = '\0';
/* Check parameters */
if (!commands || !numCommands || !path)
goto done;
/* Clear the stack */
Memset(stack, 0, sizeof(stack));
/* Look for "set default=value", where value is not a variable */
for (i = 0; i < numCommands; i++)
{
const GRUBCommand* cmd = &commands[i];
if (cmd->argc < 2)
continue;
if (Strcmp(cmd->argv[0], "set") == 0 &&
Strncmp(cmd->argv[1], "default=", 8) == 0 &&
cmd->argv[1][8] != '$')
{
defaultValue = cmd->argv[1] + 8;
break;
}
}
/* If not found, then fallback on the "0" menu entry */
if (!defaultValue)
{
defaultValue = "0";
hasDefault = FALSE;
}
/* Split 'default' value into parts */
if (StrSplit(defaultValue, ">", &arr) != 0 || arr.size < 1)
goto done;
#if defined(DEBUG_GRUBCFG)
for (i = 0; i < arr.size; i++)
{
PRINTF("DEFAULT{%s}\n", arr.data[i]);
}
#endif
/* Look for matching 'menuentry' */
for (i = 0; i < numCommands; i++)
{
const GRUBCommand* cmd = &commands[i];
if (Strcmp(cmd->argv[0], "menuentry") == 0)
{
#if defined(DEBUG_GRUBCFG)
_Indent(top);
PRINTF0("menuentry\n");
_Indent(top);
PRINTF0("{\n");
#endif
/* Check for stack overflow */
if (top == STACK_SIZE)
goto done;
/* Push element onto stack */
stack[top].command = cmd;
top++;
}
else if (Strcmp(cmd->argv[0], "submenu") == 0)
{
#if defined(DEBUG_GRUBCFG)
_Indent(top);
PRINTF0("submenu\n");
_Indent(top);
PRINTF0("{\n");
#endif
/* Check for stack overflow */
if (top == STACK_SIZE)
goto done;
/* Push element onto stack */
stack[top].command = cmd;
top++;
}
else if (Strcmp(cmd->argv[0], "initrd") == 0 && cmd->argc == 2)
{
if (top && Strcmp(stack[top-1].command->argv[0], "menuentry") == 0)
Strcpy(stack[top-1].initrd, cmd->argv[1]);
}
else if (Strcmp(cmd->argv[0], "initrdefi") == 0 && cmd->argc == 2)
{
if (top && Strcmp(stack[top-1].command->argv[0], "menuentry") == 0)
Strcpy(stack[top-1].initrd, cmd->argv[1]);
}
else if (Strcmp(cmd->argv[0], "}") == 0)
{
if (top)
{
/* Reset the depth at next level */
if (top != STACK_SIZE)
stack[top].index = 0;
if (Strcmp(stack[top-1].command->argv[0], "menuentry") == 0)
{
if (_Match(&arr, hasDefault, stack, top, matched))
{
Strcpy(title, stack[top-1].command->argv[1]);
Strcpy(path, stack[top-1].initrd);
rc = 0;
goto done;
PRINTF0("MATCH!!!\n");
}
#if defined(DEBUG_GRUBCFG)
{
UINTN j;
_Indent(top);
for (j = 0; j < top; j++)
{
PRINTF("%lu>", (unsigned long)stack[j].index);
}
PRINTF(": %s\n", stack[top-1].initrd);
}
#endif
}
/* Pop the stack */
top--;
stack[top].initrd[0] = '\0';
stack[top].index++;
#if defined(DEBUG_GRUBCFG)
_Indent(top);
PRINTF0("}\n");
#endif
}
}
(void)cmd;
}
rc = 0;
done:
StrArrRelease(&arr);
return rc;
}