Example #1
0
static char *
adjust_file (const char *in, grub_size_t len)
{
  const char *comma, *ptr, *rest;
  char *ret, *outptr;
  int overhead = 0;
  int part = -1, subpart = -1;
  if (in[0] != '(')
    return grub_legacy_escape (in, len);
  for (ptr = in + 1; ptr < in + len && *ptr && *ptr != ')'
	 && *ptr != ','; ptr++)
    if (*ptr == '\'' || *ptr == '\\')
      overhead++;
  comma = ptr;
  if (*comma != ',')
    return grub_legacy_escape (in, len);
  part = grub_strtoull (comma + 1, (char **) &rest, 0);
  if (rest[0] == ',' && rest[1] >= 'a' && rest[1] <= 'z')
    {
      subpart = rest[1] - 'a';
      rest += 2;
    }
  for (ptr = rest; ptr < in + len && *ptr; ptr++)
    if (*ptr == '\'' || *ptr == '\\')
      overhead++;

  /* 35 is enough for any 2 numbers.  */
  ret = grub_malloc (ptr - in + overhead + 35);
  if (!ret)
    return NULL;

  outptr = ret;
  for (ptr = in; ptr < in + len && ptr <= comma; ptr++)
    {
      if (*ptr == '\'' || *ptr == '\\')
	*outptr++ = '\\';
      
      *outptr++ = *ptr;
    }
  if (subpart != -1)
    grub_snprintf (outptr, 35, "%d,%d", part + 1, subpart + 1);
  else
    grub_snprintf (outptr, 35, "%d", part + 1);
  while (*outptr)
    outptr++;
  for (ptr = rest; ptr < in + len; ptr++)
    {
      if (*ptr == '\'' || *ptr == '\\')
	*outptr++ = '\\';
      
      *outptr++ = *ptr;
    }
  *outptr = 0;
  return ret;
}
Example #2
0
char *
grub_legacy_parse (const char *buf, char **entryname, char **suffix)
{
  const char *ptr;
  const char *cmdname;
  unsigned i, cmdnum;
  char *args[ARRAY_SIZE (legacy_commands[0].argt)];

  *suffix = NULL;

  for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
  if (!*ptr || *ptr == '#')
    {
      char *ret;
      int len = grub_strlen (buf);
      ret = grub_malloc (len + 2);
      grub_memcpy (ret, buf, len);
      if (len && ret[len - 1] == '\n')
	ret[len] = 0;
      else
	{
	  ret[len] = '\n';
	  ret[len + 1] = 0;
	}
      return ret;
    }

  cmdname = ptr;
  for (ptr = buf; *ptr && !grub_isspace (*ptr) && *ptr != '='; ptr++);

  for (cmdnum = 0; cmdnum < ARRAY_SIZE (legacy_commands); cmdnum++)
    if (grub_strncmp (legacy_commands[cmdnum].name, cmdname, ptr - cmdname) == 0
	&& legacy_commands[cmdnum].name[ptr - cmdname] == 0
	&& (!(*entryname != NULL && (legacy_commands[cmdnum].flags
				     & FLAG_NO_MENUENTRY)))
	&& (!(*entryname == NULL && (legacy_commands[cmdnum].flags
				     & FLAG_MENUENTRY_ONLY))))
      break;
  if (cmdnum == ARRAY_SIZE (legacy_commands))
    return grub_xasprintf ("# Unsupported legacy command: %s\n", buf);

  for (; grub_isspace (*ptr) || *ptr == '='; ptr++);

  if (legacy_commands[cmdnum].flags & FLAG_TITLE)
    {
      const char *ptr2;
      ptr2 = ptr + grub_strlen (ptr);
      while (ptr2 > ptr && grub_isspace (*(ptr2 - 1)))
	ptr2--;
      *entryname = grub_strndup (ptr, ptr2 - ptr);
      return NULL;
    }

  if (legacy_commands[cmdnum].flags & FLAG_TERMINAL)
    {
      int dumb = 0, lines = 24;
#ifdef TODO
      int no_echo = 0, no_edit = 0;
#endif
      int hercules = 0;
      int console = 0, serial = 0, graphics = 0;
      /* Big enough for any possible resulting command. */
      char outbuf[512] = "";
      char *outptr;
      while (*ptr)
	{
	  /*	  "[--timeout=SECS] [--silent]"
		  " [console] [serial] [hercules]"*/
	  if (grub_memcmp (ptr, "--dumb", sizeof ("--dumb") - 1) == 0)
	    dumb = 1;
#ifdef TODO
	  if (grub_memcmp (ptr, "--no-echo", sizeof ("--no-echo") - 1) == 0)
	    no_echo = 1;

	  if (grub_memcmp (ptr, "--no-edit", sizeof ("--no-edit") - 1) == 0)
	    no_edit = 1;
#endif
	  if (grub_memcmp (ptr, "--lines=", sizeof ("--lines=") - 1) == 0)
	    {
	      lines = grub_strtoul (ptr + sizeof ("--lines=") - 1, 0, 0);
	      if (grub_errno)
		{
		  lines = 24;
		  grub_errno = GRUB_ERR_NONE;
		}
	    }

	  if (grub_memcmp (ptr, "console", sizeof ("console") - 1) == 0)
	    console = 1;

	  if (grub_memcmp (ptr, "serial", sizeof ("serial") - 1) == 0)
	    serial = 1;
	  if (grub_memcmp (ptr, "hercules", sizeof ("hercules") - 1) == 0)
	    hercules = 1;
	  if (grub_memcmp (ptr, "graphics", sizeof ("graphics") - 1) == 0)
	    graphics = 1;
	  while (*ptr && !grub_isspace (*ptr))
	    ptr++;
	  while (*ptr && grub_isspace (*ptr))
	    ptr++;
	}

      if (!console && !serial && !hercules && !graphics)
	return grub_strdup ("terminal_input; terminal_output; terminfo\n");

      outptr = outbuf;

      if (graphics)
	outptr = grub_stpcpy (outptr, "insmod all_video; ");

      outptr = grub_stpcpy (outptr, "terminal_input ");
      if (serial)
	outptr = grub_stpcpy (outptr, "serial ");
      if (console || hercules || graphics)
	outptr = grub_stpcpy (outptr, "console ");
      outptr = grub_stpcpy (outptr, "; terminal_output ");
      if (serial)
	outptr = grub_stpcpy (outptr, "serial ");
      if (console)
	outptr = grub_stpcpy (outptr, "console ");
      if (hercules)
	outptr = grub_stpcpy (outptr, "mda_text ");
      if (graphics)
	outptr = grub_stpcpy (outptr, "gfxterm ");
      outptr = grub_stpcpy (outptr, "; ");
      *outptr = '\0';
      if (serial)
	{
	  grub_snprintf (outptr, outbuf + sizeof (outbuf) - outptr,
			 "terminfo serial -g 80x%d %s; ",
			 lines, dumb ? "dumb" : "vt100");
	  outptr += grub_strlen (outptr);
	}

      grub_strcpy (outptr, "\n");

      return grub_strdup (outbuf);
    }

  grub_memset (args, 0, sizeof (args));

  {
    int hold_arg = 0;
    const char *curarg = NULL; 
    for (i = 0; i < legacy_commands[cmdnum].argc; i++)
      {
 	grub_size_t curarglen;
	if (hold_arg)
	  {
	    ptr = curarg;
	    hold_arg = 0;
	  }
	for (; grub_isspace (*ptr); ptr++);
	curarg = ptr;
	if (!*curarg)
	  break;
	for (; *ptr && !grub_isspace (*ptr); ptr++);
	if (i != legacy_commands[cmdnum].argc - 1
	    || (legacy_commands[cmdnum].flags & FLAG_IGNORE_REST))
	  curarglen = ptr - curarg;
	else
	  {
	    curarglen = grub_strlen (curarg);
	    while (curarglen > 0 && grub_isspace (curarg[curarglen - 1]))
	      curarglen--;
	  }
	if (*ptr)
	  ptr++;
	switch (legacy_commands[cmdnum].argt[i])
	  {
	  case TYPE_FILE_NO_CONSUME:
	    hold_arg = 1;
	  case TYPE_PARTITION:
	  case TYPE_FILE:
	    args[i] = adjust_file (curarg, curarglen);
	    break;

	  case TYPE_REST_VERBATIM:
	    {
	      char *outptr, *outptr0;
	      int overhead = 3;
	      ptr = curarg;
	      while (*ptr)
		{
		  for (; *ptr && grub_isspace (*ptr); ptr++);
		  for (; *ptr && !grub_isspace (*ptr); ptr++)
		    if (*ptr == '\'')
		      overhead += 3;
		  if (*ptr)
		    ptr++;
		  overhead += 3;
		}
		
	      outptr0 = args[i] = grub_malloc (overhead + (ptr - curarg));
	      if (!outptr0)
		return NULL;
	      ptr = curarg;
	      outptr = outptr0;
	      while (*ptr)
		{
		  for (; *ptr && grub_isspace (*ptr); ptr++);
		  if (outptr != outptr0)
		    *outptr++ = ' ';
		  *outptr++ = '\'';
		  for (; *ptr && !grub_isspace (*ptr); ptr++)
		    {
		      if (*ptr == '\'')
			{
			  *outptr++ = '\'';
			  *outptr++ = '\\';
			  *outptr++ = '\'';
			  *outptr++ = '\'';
			}
		      else
			*outptr++ = *ptr;
		    }
		  *outptr++ = '\'';
		  if (*ptr)
		    ptr++;
		}
	      *outptr++ = 0;
	    }
	    break;

	  case TYPE_VERBATIM:
	    args[i] = grub_legacy_escape (curarg, curarglen);
	    break;
	  case TYPE_WITH_CONFIGFILE_OPTION:
	  case TYPE_FORCE_OPTION:
	  case TYPE_NOAPM_OPTION:
	  case TYPE_TYPE_OR_NOMEM_OPTION:
	  case TYPE_OPTION:
	    if (is_option (legacy_commands[cmdnum].argt[i], curarg, curarglen))
	      {
		args[i] = grub_strndup (curarg, curarglen);
		break;
	      }
	    args[i] = grub_strdup ("");
	    hold_arg = 1;
	    break;
	  case TYPE_INT:
	    {
	      const char *brk;
	      int base = 10;
	      brk = curarg;
	      if (brk[0] == '0' && brk[1] == 'x')
		{
		  base = 16;
		  brk += 2;
		}
	      else if (brk[0] == '0')
		base = 8;
	      for (; *brk && brk < curarg + curarglen; brk++)
		{
		  if (base == 8 &&  (*brk == '8' || *brk == '9'))
		    break;
		  if (grub_isdigit (*brk))
		    continue;
		  if (base != 16)
		    break;
		  if (!(*brk >= 'a' && *brk <= 'f')
		      && !(*brk >= 'A' && *brk <= 'F'))
		    break;
		}
	      if (brk == curarg)
		args[i] = grub_strdup ("0");
	      else
		args[i] = grub_strndup (curarg, brk - curarg);
	    }
	    break;
	  case TYPE_VBE_MODE:
	    {
	      unsigned mod;
	      struct grub_vesa_mode_table_entry *modedesc;

	      mod = grub_strtoul (curarg, 0, 0);
	      if (grub_errno)
		{
		  mod = 0;
		  grub_errno = GRUB_ERR_NONE;
		}
	      if (mod < GRUB_VESA_MODE_TABLE_START
		  || mod > GRUB_VESA_MODE_TABLE_END)
		{
		  args[i] = grub_strdup ("auto");
		  break;
		}
	      modedesc = &grub_vesa_mode_table[mod - GRUB_VESA_MODE_TABLE_START];
	      if (!modedesc->width)
		{
		  args[i] = grub_strdup ("auto");
		  break;
		}
	      args[i] = grub_xasprintf ("%ux%ux%u",
					modedesc->width, modedesc->height,
					modedesc->depth);
	      break;
	    }
	  case TYPE_BOOL:
	    if (curarglen == 2 && curarg[0] == 'o' && curarg[1] == 'n')
	      args[i] = grub_strdup ("1");
	    else
	      args[i] = grub_strdup ("0");
	    break;
	  }
      }
  }

  while (legacy_commands[cmdnum].argc > 0
	 && args[legacy_commands[cmdnum].argc - 1] == NULL
	 && (legacy_commands[cmdnum].flags & FLAG_FALLBACK_AVAILABLE)
	 && args[legacy_commands[cmdnum + 1].argc] == NULL)
    cmdnum++;

  for (; i < legacy_commands[cmdnum].argc; i++)
    switch (legacy_commands[cmdnum].argt[i])
      {
      case TYPE_FILE_NO_CONSUME:
      case TYPE_PARTITION:
      case TYPE_FILE:
      case TYPE_REST_VERBATIM:
      case TYPE_VERBATIM:
      case TYPE_WITH_CONFIGFILE_OPTION:
      case TYPE_FORCE_OPTION:
      case TYPE_NOAPM_OPTION:
      case TYPE_TYPE_OR_NOMEM_OPTION:
      case TYPE_OPTION:	
	args[i] = grub_strdup ("");
	break;
      case TYPE_BOOL:
      case TYPE_INT:
	args[i] = grub_strdup ("0");
	break;
      case TYPE_VBE_MODE:    
	args[i] = grub_strdup ("auto");
	break;
      }

  if (legacy_commands[cmdnum].flags & FLAG_COLOR_INVERT)
    {
      char *corig = args[legacy_commands[cmdnum].argc - 1];
      char *slash = grub_strchr (corig, '/');
      char *invert;
      grub_size_t len;

      len = grub_strlen (corig);
      if (!slash)
	{
	  grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid color specification `%s'"),
		      args[0]);
	  return NULL;
	}
      invert = grub_malloc (len + 1);
      if (!invert)
	return NULL;
      grub_memcpy (invert, slash + 1, len - (slash - corig) - 1);
      invert[len - (slash - args[0]) - 1] = '/'; 
      grub_memcpy (invert + len - (slash - corig), corig, slash - corig);
      invert[len] = 0;
      args[legacy_commands[cmdnum].argc] = invert;
    }

  if (legacy_commands[cmdnum].suffix)
    {
      *suffix = grub_xasprintf (legacy_commands[cmdnum].suffix,
				args[legacy_commands[cmdnum].suffixarg]);
      if (*suffix)
	return NULL;
    }

  {
    char *ret = grub_xasprintf (legacy_commands[cmdnum].map, args[0], args[1],
				args[2], args[3]);
    grub_free (args[0]);
    grub_free (args[1]);
    grub_free (args[2]);
    grub_free (args[3]);
    return ret;
  }
}
Example #3
0
int
main (int argc, char **argv)
{
    FILE *in, *out;
    char *entryname = NULL;
    char *buf = NULL;
    size_t bufsize = 0;
    char *suffix = xstrdup ("");
    int suffixlen = 0;

    if (argc >= 2 && argv[1][0] == '-')
    {
        fprintf (stdout, "Usage: %s [INFILE [OUTFILE]]\n", argv[0]);
        return 0;
    }

    if (argc >= 2)
    {
        in = fopen (argv[1], "r");
        if (!in)
        {
            fprintf (stderr, "Couldn't open %s for reading: %s\n",
                     argv[1], strerror (errno));
            return 1;
        }
    }
    else
        in = stdin;

    if (argc >= 3)
    {
        out = fopen (argv[2], "w");
        if (!out)
        {
            if (in != stdin)
                fclose (in);
            fprintf (stderr, "Couldn't open %s for writing: %s\n",
                     argv[2], strerror (errno));
            return 1;
        }
    }
    else
        out = stdout;

    while (1)
    {
        char *parsed;

        if (getline (&buf, &bufsize, in) < 0)
            break;

        {
            char *oldname = NULL;
            char *newsuffix;

            oldname = entryname;
            parsed = grub_legacy_parse (buf, &entryname, &newsuffix);
            if (newsuffix)
            {
                suffixlen += strlen (newsuffix);
                suffix = xrealloc (suffix, suffixlen + 1);
                strcat (suffix, newsuffix);
            }
            if (oldname != entryname && oldname)
                fprintf (out, "}\n\n");
            if (oldname != entryname)
            {
                char *escaped = grub_legacy_escape (entryname, strlen (entryname));
                fprintf (out, "menuentry \'%s\' {\n", escaped);
                free (escaped);
                free (oldname);
            }
        }

        if (parsed)
            fprintf (out, "%s%s", entryname ? "  " : "", parsed);
        free (parsed);
        parsed = NULL;
    }

    if (entryname)
        fprintf (out, "}\n\n");

    fwrite (suffix, 1, suffixlen, out);

    free (buf);
    free (suffix);
    free (entryname);

    if (in != stdin)
        fclose (in);
    if (out != stdout)
        fclose (out);

    return 0;
}