summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2001-03-23 20:44:04 +0000
committerGerald Carter <jerry@samba.org>2001-03-23 20:44:04 +0000
commiteff4d481f772f00df2480be95823f364a4b8c136 (patch)
treef8630a45c61ed1a80c4f8b7c8c9ab258bfabe7e5
parentc927d7ee82c61806fbdc96b8ac71ccc95cf7f003 (diff)
downloadsamba-eff4d481f772f00df2480be95823f364a4b8c136.tar.gz
samba-eff4d481f772f00df2480be95823f364a4b8c136.tar.xz
samba-eff4d481f772f00df2480be95823f364a4b8c136.zip
added readline to smbclient and rpcclient from HEAD. Also added a
completion function to rpcclient
-rw-r--r--source/Makefile.in2
-rw-r--r--source/client/client.c196
-rw-r--r--source/include/proto.h6
-rw-r--r--source/rpcclient/rpcclient.c90
4 files changed, 165 insertions, 129 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 00af7e7290a..4bd27095658 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -111,7 +111,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \
- nsswitch/wb_client.o nsswitch/wb_common.o \
+ nsswitch/wb_client.o nsswitch/wb_common.o lib/readline.o \
$(TDB_OBJ)
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
diff --git a/source/client/client.c b/source/client/client.c
index 8e32b40629a..3f9eeac368e 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -40,11 +40,11 @@ static pstring username;
static pstring workgroup;
static char *cmdstr;
static BOOL got_pass;
-static int io_bufsize = 65520;
+static int io_bufsize = 64512;
extern struct in_addr ipzero;
static int name_type = 0x20;
-
+static int max_protocol = PROTOCOL_NT1;
extern pstring user_socket_options;
static int process_tok(fstring tok);
@@ -1599,27 +1599,6 @@ static BOOL list_servers(char *wk_grp)
return True;
}
-#if defined(HAVE_LIBREADLINE)
-# if defined(HAVE_READLINE_HISTORY_H) || defined(HAVE_HISTORY_H)
-/****************************************************************************
-history
-****************************************************************************/
-static void cmd_history(void)
-{
- HIST_ENTRY **hlist;
- register int i;
-
- hlist = history_list (); /* Get pointer to history list */
-
- if (hlist) /* If list not empty */
- {
- for (i = 0; hlist[i]; i++) /* then display it */
- DEBUG(0, ("%d: %s\n", i, hlist[i]->line));
- }
-}
-# endif
-#endif
-
/* Some constants for completing filename arguments */
#define COMPL_NONE 0 /* No completions */
@@ -1675,9 +1654,7 @@ struct
{"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
{"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
-#ifdef HAVE_LIBREADLINE
{"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
-#endif
{"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
{"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
};
@@ -1735,39 +1712,6 @@ static void cmd_help(void)
}
}
-#ifndef HAVE_LIBREADLINE
-/****************************************************************************
-wait for keyboard activity, swallowing network packets
-****************************************************************************/
-static void wait_keyboard(void)
-{
- fd_set fds;
- struct timeval timeout;
-
- while (1) {
- FD_ZERO(&fds);
- FD_SET(cli->fd,&fds);
- FD_SET(fileno(stdin),&fds);
-
- timeout.tv_sec = 20;
- timeout.tv_usec = 0;
- sys_select_intr(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
-
- if (FD_ISSET(fileno(stdin),&fds))
- return;
-
- /* We deliberately use receive_smb instead of
- client_receive_smb as we want to receive
- session keepalives and then drop them here.
- */
- if (FD_ISSET(cli->fd,&fds))
- receive_smb(cli->fd,cli->inbuf,0);
-
- cli_chkpath(cli, "\\");
- }
-}
-#endif
-
/****************************************************************************
process a -c command string
****************************************************************************/
@@ -1807,56 +1751,95 @@ static void process_command_string(char *cmd)
}
/****************************************************************************
-process commands on stdin
+handle completion of commands for readline
****************************************************************************/
-static void process_stdin(void)
+static char **completion_fn(char *text, int start, int end)
{
- pstring line;
- char *ptr;
+#define MAX_COMPLETIONS 100
+ char **matches;
+ int i, count=0;
-#ifdef HAVE_LIBREADLINE
-/* Minimal readline support, 29Jun1999, s.xenitellis@rhbnc.ac.uk */
-#ifdef PROMPTSIZE
-#undef PROMPTSIZE
-#endif
-#define PROMPTSIZE 2048
- char prompt_str[PROMPTSIZE]; /* This holds the buffer "smb: \dir1\> " */
-
- char *temp; /* Gets the buffer from readline() */
- temp = (char *)NULL;
-#endif
- while (!feof(stdin)) {
- fstring tok;
- int i;
-#ifdef HAVE_LIBREADLINE
- if ( temp != (char *)NULL )
- {
- free( temp ); /* Free memory allocated every time by readline() */
- temp = (char *)NULL;
+ /* for words not at the start of the line fallback to filename completion */
+ if (start) return NULL;
+
+ matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS);
+ if (!matches) return NULL;
+
+ matches[count++] = strdup(text);
+ if (!matches[0]) return NULL;
+
+ for (i=0;commands[i].fn && count < MAX_COMPLETIONS-1;i++) {
+ if (strncmp(text, commands[i].name, strlen(text)) == 0) {
+ matches[count] = strdup(commands[i].name);
+ if (!matches[count]) return NULL;
+ count++;
}
+ }
- slprintf( prompt_str, PROMPTSIZE - 1, "smb: %s> ", cur_dir );
+ if (count == 2) {
+ free(matches[0]);
+ matches[0] = strdup(matches[1]);
+ }
+ matches[count] = NULL;
+ return matches;
+}
- temp = readline( prompt_str ); /* We read the line here */
- if ( !temp )
- break; /* EOF occured */
+/****************************************************************************
+make sure we swallow keepalives during idle time
+****************************************************************************/
+static void readline_callback(void)
+{
+ fd_set fds;
+ struct timeval timeout;
+ static time_t last_t;
+ time_t t;
- if ( *temp ) /* If non-empty line, save to history */
- add_history (temp);
-
- strncpy( line, temp, 1023 ); /* Maximum size of (pstring)line. Null is guarranteed. */
-#else
- /* display a prompt */
- DEBUG(0,("smb: %s> ", cur_dir));
- dbgflush( );
-
- wait_keyboard();
+ t = time(NULL);
+
+ if (t - last_t < 5) return;
+
+ last_t = t;
+
+ again:
+ FD_ZERO(&fds);
+ FD_SET(cli->fd,&fds);
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ sys_select_intr(cli->fd+1,&fds,&timeout);
+
+ /* We deliberately use receive_smb instead of
+ client_receive_smb as we want to receive
+ session keepalives and then drop them here.
+ */
+ if (FD_ISSET(cli->fd,&fds)) {
+ receive_smb(cli->fd,cli->inbuf,0);
+ goto again;
+ }
+
+ cli_chkpath(cli, "\\");
+}
+
+
+/****************************************************************************
+process commands on stdin
+****************************************************************************/
+static void process_stdin(void)
+{
+ char *ptr;
+
+ while (1) {
+ fstring tok;
+ fstring prompt;
+ char *line;
+ int i;
- /* and get a response */
- if (!fgets(line,1000,stdin))
- break;
-#endif
+ /* display a prompt */
+ slprintf(prompt, sizeof(prompt), "smb: %s> ", cur_dir);
+ line = smb_readline(prompt, readline_callback, completion_fn);
+
+ if (!line) break;
/* special case - first char is ! */
if (*line == '!') {
@@ -1921,6 +1904,8 @@ struct cli_state *do_connect(char *server, char *share)
return NULL;
}
+ c->protocol = max_protocol;
+
if (!cli_session_request(c, &calling, &called)) {
char *p;
DEBUG(0,("session request to %s failed (%s)\n",
@@ -2199,6 +2184,7 @@ static int do_message_op(void)
extern FILE *dbf;
extern char *optarg;
extern int optind;
+ int old_debug;
pstring query_host;
BOOL message = False;
extern char tar_type;
@@ -2219,11 +2205,7 @@ static int do_message_op(void)
*new_name_resolve_order = 0;
DEBUGLEVEL = 2;
-
-#ifdef HAVE_LIBREADLINE
- /* Allow conditional parsing of the ~/.inputrc file. */
- rl_readline_name = "smbclient";
-#endif
+
setup_logging(pname,True);
/*
@@ -2255,9 +2237,11 @@ static int do_message_op(void)
in_client = True; /* Make sure that we tell lp_load we are */
+ old_debug = DEBUGLEVEL;
if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
}
+ DEBUGLEVEL = old_debug;
codepage_initialise(lp_client_code_page());
@@ -2472,7 +2456,7 @@ static int do_message_op(void)
pstrcpy(term_code, optarg);
break;
case 'm':
- /* no longer supported */
+ max_protocol = interpret_protocol(optarg, max_protocol);
break;
case 'W':
pstrcpy(workgroup,optarg);
@@ -2533,7 +2517,7 @@ static int do_message_op(void)
if (message) {
return do_message_op();
}
-
+
if (!process(base_directory)) {
return(1);
}
diff --git a/source/include/proto.h b/source/include/proto.h
index d9b30306913..a5023bd87e3 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -164,6 +164,12 @@ int ms_fnmatch(char *pattern, char *string);
pid_t pidfile_pid(char *name);
void pidfile_create(char *name);
+/*The following definitions come from lib/readline.c */
+
+char *smb_readline(char *prompt, void (*callback)(void),
+ char **(completion_fn)(char *text, int start, int end));
+void cmd_history(void);
+
/*The following definitions come from lib/replace.c */
char *rep_inet_ntoa(struct in_addr ip);
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index 210fc441c13..56a9f90978a 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -30,8 +30,72 @@ extern struct cmd_set lsarpc_commands[];
extern struct cmd_set samr_commands[];
extern struct cmd_set spoolss_commands[];
+/* List to hold groups of commands */
+static struct cmd_list {
+ struct cmd_list *prev, *next;
+ struct cmd_set *cmd_set;
+} *cmd_list;
+
DOM_SID domain_sid;
+
+/****************************************************************************
+handle completion of commands for readline
+****************************************************************************/
+static char **completion_fn(char *text, int start, int end)
+{
+#define MAX_COMPLETIONS 100
+ char **matches;
+ int i, count=0;
+ struct cmd_list *commands = cmd_list;
+
+#if 0 /* JERRY */
+ /* FIXME!!! -- what to do when completing argument? */
+ /* for words not at the start of the line fallback
+ to filename completion */
+ if (start)
+ return NULL;
+#endif
+
+ /* make sure we have a list of valid commands */
+ if (!commands)
+ return NULL;
+
+ matches = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS);
+ if (!matches) return NULL;
+
+ matches[count++] = strdup(text);
+ if (!matches[0]) return NULL;
+
+ while (commands && count < MAX_COMPLETIONS-1)
+ {
+ if (!commands->cmd_set)
+ break;
+
+ for (i=0; commands->cmd_set[i].name; i++)
+ {
+ if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
+ commands->cmd_set[i].fn)
+ {
+ matches[count] = strdup(commands->cmd_set[i].name);
+ if (!matches[count])
+ return NULL;
+ count++;
+ }
+ }
+
+ commands = commands->next;
+
+ }
+
+ if (count == 2) {
+ free(matches[0]);
+ matches[0] = strdup(matches[1]);
+ }
+ matches[count] = NULL;
+ return matches;
+}
+
/***********************************************************************
* read in username/password credentials from a file
*/
@@ -192,12 +256,6 @@ void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
fstrcpy(creds->domain, domain);
}
-/* List to hold groups of commands */
-
-static struct cmd_list {
- struct cmd_list *prev, *next;
- struct cmd_set *cmd_set;
-} *cmd_list;
static uint32 cmd_help(struct cli_state *cli, int argc, char **argv)
{
@@ -454,11 +512,6 @@ static void usage(char *pname)
charset_initialise();
setlinebuf(stdout);
-#ifdef HAVE_LIBREADLINE
- /* Allow conditional parsing of the ~/.inputrc file. */
- rl_readline_name = "rpcclient";
-#endif
-
DEBUGLEVEL = 1;
/* Parse options */
@@ -603,23 +656,16 @@ static void usage(char *pname)
/* Loop around accepting commands */
while(1) {
pstring prompt, cmd;
+ char *line;
+ uint32 result;
ZERO_STRUCT(cmd);
slprintf(prompt, sizeof(prompt) - 1, "rpcclient $> ");
-#if HAVE_READLINE
- cmd = readline(prompt);
-#else
- printf("%s", prompt);
+ line = smb_readline(prompt, NULL, completion_fn);
- if (!fgets(cmd, sizeof(cmd) - 1, stdin)) {
- break;
- }
-
- cmd[strlen(cmd) - 1] = '\0';
-#endif
- process_cmd(&cli, cmd);
+ result = process_cmd(&cli, line);
}
return 0;