diff options
Diffstat (limited to 'source3/rpcclient/rpcclient.c')
-rw-r--r-- | source3/rpcclient/rpcclient.c | 185 |
1 files changed, 106 insertions, 79 deletions
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 81bb62486a..2609519dc4 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -3,7 +3,6 @@ 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 @@ -25,12 +24,7 @@ DOM_SID domain_sid; - -/* 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. - */ +/* List to hold groups of commands */ static struct cmd_list { struct cmd_list *prev, *next; @@ -170,28 +164,21 @@ static char* next_command (char** cmdstr) if (p) *p = '\0'; pstrcpy(command, *cmdstr); - *cmdstr = p + 1; + *cmdstr = p; 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")) - fstrcpy(username,getenv("USER")); + pstrcpy(username,getenv("USER")); if (*username == 0 && getenv("LOGNAME")) - fstrcpy(username,getenv("LOGNAME")); + pstrcpy(username,getenv("LOGNAME")); if (*username == 0) { - fstrcpy(username,"GUEST"); + pstrcpy(username,"GUEST"); } return; @@ -384,7 +371,7 @@ static NTSTATUS cmd_quit(struct cli_state *cli, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; /* NOTREACHED */ } -/* Built in rpcclient commands */ +/* Build in rpcclient commands */ static struct cmd_set rpcclient_commands[] = { @@ -445,105 +432,145 @@ static void add_command_set(struct cmd_set *cmd_set) DLIST_ADD(cmd_list, entry); } - -/** - * 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) +static NTSTATUS do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry, + char *cmd) { - NTSTATUS result; - - TALLOC_CTX *mem_ctx; + 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 mem_ctx */ + /* Create argument list */ - if (!(mem_ctx = talloc_init("do_cmd"))) { - DEBUG(0, ("talloc_init() failed\n")); - return NT_STATUS_UNSUCCESSFUL; + argv = (char **)malloc(sizeof(char *) * argc); + memset(argv, 0, sizeof(char *) * argc); + + if (!argv) { + fprintf(stderr, "out of memory\n"); + result = NT_STATUS_NO_MEMORY; + goto done; + } + + p = cmd; + argc = 0; + + goto again; } - /* Open pipe */ + /* Call the function */ - 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; - } + if (cmd_entry->fn) { + TALLOC_CTX *mem_ctx; - /* Run command */ + /* Create mem_ctx */ - result = cmd_entry->fn(cli, mem_ctx, argc, (char **) argv); + if (!(mem_ctx = talloc_init("do_cmd"))) { + DEBUG(0, ("talloc_init() failed\n")); + goto done; + } - /* Cleanup */ + /* Open pipe */ - if (cmd_entry->pipe_idx != -1) - cli_nt_session_close(cli); + 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; + } - talloc_destroy(mem_ctx); + /* Run command */ + + result = cmd_entry->fn(cli, mem_ctx, argc, argv); + /* Cleanup */ + + if (cmd_entry->pipe_idx != -1) + cli_nt_session_close(cli); + + talloc_destroy(mem_ctx); + + } else { + fprintf (stderr, "Invalid command\n"); + goto done; + } + + done: + + /* Cleanup */ + + 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 ret; - int argc; - char **argv = NULL; + int len = 0; + + if (cmd[strlen(cmd) - 1] == '\n') + cmd[strlen(cmd) - 1] = '\0'; - if ((ret = poptParseArgvString(cmd, &argc, (const char ***) &argv)) != 0) { - fprintf(stderr, "rpcclient: %s\n", poptStrerror(ret)); - return NT_STATUS_UNSUCCESSFUL; + if (!next_token(&p, buf, " ", sizeof(buf))) { + return NT_STATUS_OK; } + /* 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(argv[0], temp_set->name)) { - if (!temp_set->fn) { - fprintf (stderr, "Invalid command\n"); - goto out_free; - } + while(temp_set->name) { + if (strequal(buf, temp_set->name)) { + found = True; + result = do_cmd(cli, temp_set, cmd); - result = do_cmd(cli, temp_set, argc, argv); - - goto out_free; + goto done; } temp_set++; } } - if (argv[0]) { - printf("command not found: %s\n", argv[0]); + done: + if (!found && buf[0]) { + printf("command not found: %s\n", buf); + return NT_STATUS_OK; } -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; } |