Exemple #1
0
static dbus_bool_t
test_command_line (const char *arg1, ...)
{
  int i, original_argc, shell_argc;
  char **shell_argv;
  char **original_argv;
  char *command_line, *tmp;
  DBusString str;
  DBusList *list = NULL, *node;
  va_list var_args;
  DBusError error;

  va_start (var_args, arg1);
  _dbus_list_append (&list, (char *)arg1);
  do
    {
      tmp = va_arg (var_args, char *);
      if (!tmp)
        break;
      _dbus_list_append (&list, tmp);
    } while (tmp);
  va_end (var_args);

  original_argc = _dbus_list_get_length (&list);
  original_argv = dbus_new (char *, original_argc);
  _dbus_string_init (&str);
  for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node;
       i++, node = _dbus_list_get_next_link (&list, node))
    {
      original_argv[i] = node->data;
      if (i > 0)
        _dbus_string_append_byte (&str, ' ');
      _dbus_string_append (&str, original_argv[i]);
    }
  
  _dbus_list_clear (&list);
  command_line = _dbus_string_get_data (&str);
  printf ("\n\nTesting command line '%s'\n", command_line);

  dbus_error_init (&error);
  if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error))
    {
      fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : "");
      return FALSE;
    }
  else
    {
      if (shell_argc != original_argc)
        {
          printf ("Number of arguments returned (%d) don't match original (%d)\n",
                  shell_argc, original_argc);
          return FALSE;
        } 
      printf ("Number of arguments: %d\n", shell_argc);
      for (i = 0; i < shell_argc; i++)
        {
          char *unquoted;
          
          unquoted = _dbus_shell_unquote (original_argv[i]);
          if (strcmp (unquoted ? unquoted : "",
                      shell_argv[i] ? shell_argv[i] : ""))
            {
              printf ("Position %d, returned argument (%s) does not match original (%s)\n",
                      i, shell_argv[i], unquoted);
              dbus_free (unquoted);
              return FALSE;
            }
          dbus_free (unquoted);
          if (shell_argv[i])
            printf ("Argument %d = %s\n", i, shell_argv[i]);
        }
      
      dbus_free_string_array (shell_argv);
    }
  
  _dbus_string_free (&str);
  
  return TRUE;
}
/**
 * _dbus_shell_parse_argv:
 *
 * Parses a command line into an argument vector, in much the same way
 * the shell would, but without many of the expansions the shell would
 * perform (variable expansion, globs, operators, filename expansion,
 * etc. are not supported). The results are defined to be the same as
 * those you would get from a UNIX98 /bin/sh, as long as the input
 * contains none of the unsupported shell expansions. If the input
 * does contain such expansions, they are passed through
 * literally. Free the returned vector with dbus_free_string_array().
 *
 * @command_line: command line to parse
 * @argcp: return location for number of args
 * @argvp: return location for array of args
 * @error: error information
 **/
dbus_bool_t
_dbus_shell_parse_argv (const char *command_line,
                        int        *argcp,
                        char     ***argvp,
                        DBusError  *error)
{
    /* Code based on poptParseArgvString() from libpopt */
    int argc = 0;
    char **argv = NULL;
    DBusList *tokens = NULL;
    int i;
    DBusList *tmp_list;

    if (!command_line)
    {
        _dbus_verbose ("Command line is NULL\n");
        return FALSE;
    }

    tokens = tokenize_command_line (command_line, error);
    if (tokens == NULL)
    {
        _dbus_verbose ("No tokens for command line '%s'\n", command_line);
        return FALSE;
    }

    /* Because we can't have introduced any new blank space into the
     * tokens (we didn't do any new expansions), we don't need to
     * perform field splitting. If we were going to honor IFS or do any
     * expansions, we would have to do field splitting on each word
     * here. Also, if we were going to do any expansion we would need to
     * remove any zero-length words that didn't contain quotes
     * originally; but since there's no expansion we know all words have
     * nonzero length, unless they contain quotes.
     *
     * So, we simply remove quotes, and don't do any field splitting or
     * empty word removal, since we know there was no way to introduce
     * such things.
     */

    argc = _dbus_list_get_length (&tokens);
    argv = dbus_new (char *, argc + 1);
    if (!argv)
    {
        _DBUS_SET_OOM (error);
        goto error;
    }

    i = 0;
    tmp_list = tokens;
    while (tmp_list)
    {
        argv[i] = _dbus_shell_unquote (tmp_list->data);

        if (!argv[i])
        {
            int j;
            for (j = 0; j < i; j++)
                dbus_free(argv[j]);

            dbus_free (argv);
            _DBUS_SET_OOM (error);
            goto error;
        }

        tmp_list = _dbus_list_get_next_link (&tokens, tmp_list);
        ++i;
    }
    argv[argc] = NULL;

    _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL);
    _dbus_list_clear (&tokens);

    if (argcp)
        *argcp = argc;

    if (argvp)
        *argvp = argv;
    else
        dbus_free_string_array (argv);

    return TRUE;

error:
    _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL);
    _dbus_list_clear (&tokens);

    return FALSE;

}