From 130d49aa6bf463e53cf6d01900d4f50fba8c358c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 25 Feb 2003 23:53:38 +0000 Subject: Merge: const fixes. Merge: add popt_common_version to command line options table. Merge: mbp's rewrite of do_cmd() (This used to be commit 20f153cee38edfa93ffd60cc872a299a4f296240) --- source3/rpcclient/rpcclient.c | 197 +++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 110 deletions(-) (limited to 'source3/rpcclient/rpcclient.c') diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 2609519dc4..127506fb39 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -3,6 +3,7 @@ RPC pipe client Copyright (C) Tim Potter 2000-2001 + Copyright (C) Martin Pool 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,7 +25,12 @@ DOM_SID domain_sid; -/* List to hold groups of commands */ + +/* List to hold groups of commands. + * + * Commands are defined in a list of arrays: arrays are easy to + * statically declare, and lists are easier to dynamically extend. + */ static struct cmd_list { struct cmd_list *prev, *next; @@ -164,21 +170,31 @@ static char* next_command (char** cmdstr) if (p) *p = '\0'; pstrcpy(command, *cmdstr); - *cmdstr = p; + if (p) + *cmdstr = p + 1; + else + *cmdstr = NULL; return command; } + +/** + * Find default username from environment variables. + * + * @param username fstring to receive username; not touched if none is + * known. + **/ static void get_username (char *username) { if (getenv("USER")) - pstrcpy(username,getenv("USER")); + fstrcpy(username,getenv("USER")); if (*username == 0 && getenv("LOGNAME")) - pstrcpy(username,getenv("LOGNAME")); + fstrcpy(username,getenv("LOGNAME")); if (*username == 0) { - pstrcpy(username,"GUEST"); + fstrcpy(username,"GUEST"); } return; @@ -243,7 +259,7 @@ static void fetch_machine_sid(struct cli_state *cli) /* List the available commands on a given pipe */ static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, char **argv) + int argc, const char **argv) { struct cmd_list *tmp; struct cmd_set *tmp_set; @@ -288,7 +304,7 @@ static NTSTATUS cmd_listcommands(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Display help on commands */ static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, char **argv) + int argc, const char **argv) { struct cmd_list *tmp; struct cmd_set *tmp_set; @@ -348,7 +364,7 @@ static NTSTATUS cmd_help(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Change the debug level */ static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, char **argv) + int argc, const char **argv) { if (argc > 2) { printf("Usage: %s [debuglevel]\n", argv[0]); @@ -365,13 +381,13 @@ static NTSTATUS cmd_debuglevel(struct cli_state *cli, TALLOC_CTX *mem_ctx, } static NTSTATUS cmd_quit(struct cli_state *cli, TALLOC_CTX *mem_ctx, - int argc, char **argv) + int argc, const char **argv) { exit(0); return NT_STATUS_OK; /* NOTREACHED */ } -/* Build in rpcclient commands */ +/* Built in rpcclient commands */ static struct cmd_set rpcclient_commands[] = { @@ -432,145 +448,105 @@ static void add_command_set(struct cmd_set *cmd_set) DLIST_ADD(cmd_list, entry); } -static NTSTATUS do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry, - char *cmd) -{ - char **argv = NULL; - const char *p = cmd; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - pstring buf; - int argc = 0, i; - - /* Count number of arguments first time through the loop then - allocate memory and strdup them. */ - - again: - while(next_token(&p, buf, " ", sizeof(buf))) { - if (argv) { - argv[argc] = strdup(buf); - } - - argc++; - } - - if (!argv) { - /* Create argument list */ +/** + * Call an rpcclient function, passing an argv array. + * + * @param cmd Command to run, as a single string. + **/ +static NTSTATUS do_cmd(struct cli_state *cli, + struct cmd_set *cmd_entry, + int argc, char **argv) +{ + NTSTATUS result; + + TALLOC_CTX *mem_ctx; - argv = (char **)malloc(sizeof(char *) * argc); - memset(argv, 0, sizeof(char *) * argc); + /* Create mem_ctx */ - if (!argv) { - fprintf(stderr, "out of memory\n"); - result = NT_STATUS_NO_MEMORY; - goto done; - } - - p = cmd; - argc = 0; - - goto again; + if (!(mem_ctx = talloc_init("do_cmd"))) { + DEBUG(0, ("talloc_init() failed\n")); + return NT_STATUS_UNSUCCESSFUL; } - /* Call the function */ - - if (cmd_entry->fn) { - TALLOC_CTX *mem_ctx; - - /* Create mem_ctx */ - - if (!(mem_ctx = talloc_init("do_cmd"))) { - DEBUG(0, ("talloc_init() failed\n")); - goto done; - } - - /* Open pipe */ + /* Open pipe */ - if (cmd_entry->pipe_idx != -1) - if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { - DEBUG(0, ("Could not initialise pipe\n")); - goto done; - } - - /* Run command */ - - result = cmd_entry->fn(cli, mem_ctx, argc, argv); + if (cmd_entry->pipe_idx != -1) + if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { + DEBUG(0, ("Could not initialize pipe\n")); + return NT_STATUS_UNSUCCESSFUL; + } - /* Cleanup */ + /* Run command */ - if (cmd_entry->pipe_idx != -1) - cli_nt_session_close(cli); + result = cmd_entry->fn(cli, mem_ctx, argc, (const char **) argv); - talloc_destroy(mem_ctx); + /* Cleanup */ - } else { - fprintf (stderr, "Invalid command\n"); - goto done; - } + if (cmd_entry->pipe_idx != -1) + cli_nt_session_close(cli); - done: - - /* Cleanup */ + talloc_destroy(mem_ctx); - if (argv) { - for (i = 0; i < argc; i++) - SAFE_FREE(argv[i]); - - SAFE_FREE(argv); - } - return result; } -/* Process a command entered at the prompt or as part of -c */ +/** + * Process a command entered at the prompt or as part of -c + * + * @returns The NTSTATUS from running the command. + **/ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) { struct cmd_list *temp_list; - BOOL found = False; - pstring buf; - const char *p = cmd; NTSTATUS result = NT_STATUS_OK; - int len = 0; - - if (cmd[strlen(cmd) - 1] == '\n') - cmd[strlen(cmd) - 1] = '\0'; + int ret; + int argc; + char **argv = NULL; - if (!next_token(&p, buf, " ", sizeof(buf))) { - return NT_STATUS_OK; + if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) { + fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret)); + return NT_STATUS_UNSUCCESSFUL; } - /* strip the trainly \n if it exsists */ - len = strlen(buf); - if (buf[len-1] == '\n') - buf[len-1] = '\0'; - - /* Search for matching commands */ + /* Walk through a dlist of arrays of commands. */ for (temp_list = cmd_list; temp_list; temp_list = temp_list->next) { struct cmd_set *temp_set = temp_list->cmd_set; - while(temp_set->name) { - if (strequal(buf, temp_set->name)) { - found = True; - result = do_cmd(cli, temp_set, cmd); + while (temp_set->name) { + if (strequal(argv[0], temp_set->name)) { + if (!temp_set->fn) { + fprintf (stderr, "Invalid command\n"); + goto out_free; + } + + result = do_cmd(cli, temp_set, argc, argv); - goto done; + goto out_free; } temp_set++; } } - done: - if (!found && buf[0]) { - printf("command not found: %s\n", buf); - return NT_STATUS_OK; + if (argv[0]) { + printf("command not found: %s\n", argv[0]); } +out_free: if (!NT_STATUS_IS_OK(result)) { printf("result was %s\n", nt_errstr(result)); } + if (argv) { + /* NOTE: popt allocates the whole argv, including the + * strings, as a single block. So a single free is + * enough to release it -- we don't free the + * individual strings. rtfm. */ + free(argv); + } + return result; } @@ -612,6 +588,7 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) {"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"}, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug }, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_configfile }, + { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version}, { NULL } }; -- cgit