static int cmd_loop(int in_argc, const char *in_argv[]) { int argc; char *input, **argv; int quit = 0; char *history_path; history_path = load_history(); while (!quit) { input = readline("> "); append_history(history_path, input); if ((tokenize_command_line(input, &argc, &argv) == -1) || argc < 1) { free(input); continue; } int cmd = str_to_cmd(argv[0]); if (cmd == CMD_UNKNOWN || CMD_INTERACTIVE) { warnx("'%s': unknown command", argv[0]); free(argv); free(input); continue; } do_cmd(cmd, --argc, (const char **) ++argv); free(--argv); free(input); } return AFC_E_SUCCESS; }
/** * g_shell_parse_argv: * @command_line: command line to parse * @argcp: (out) (optional): return location for number of args, or %NULL * @argvp: (out) (optional) (array length=argcp zero-terminated=1): return * location for array of args, or %NULL * @error: (optional): return location for error, or %NULL * * 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. Possible errors are those from the #G_SHELL_ERROR * domain. Free the returned vector with g_strfreev(). * * Returns: %TRUE on success, %FALSE if error set **/ bool g_shell_parse_argv (const std::string& cmd, int& argcp, std::vector<std::string>& argvp) { /* Code based on poptParseArgvString() from libpopt */ std::vector<std::string> tokens; tokenize_command_line (tokens, cmd); if (tokens.empty()) { 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. */ argcp = tokens.size(); argvp.resize(argcp); for (unsigned int i=0; i< tokens.size(); i++) { argvp[i] = g_shell_unquote (tokens[i]); } 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; }