now, openipmish can support history commands, by up and down arrow key.
Corey:
1, the attachment is patch under directory OpenIPMI/cmdlang.
2, I can't attach the editline tar ball in this mail(too big). Please download the tar ball from http://www.thrysoee.dk/editline/libedit-20060103-2.9.tar.gz , and put the editline source code into OpenIPMI/libedit, for I reference this path by Makefile.am in OpenIPMI/cmdlang.
2, I have to trouble you to add the libedit into OpenIPMI automake and autoconf scripts.
Bugs:
does not support Ctrl+l to perform redisplay, for editline does not support keymap modification, and I can't register a hook for Ctrl+l.
ToDo:
1, add two commands for openipmish (clear, and history), if necessary.
2, add commands auto completing if necessary.
Best regards.
Coly
Index: Makefile.am
===================================================================
RCS file: /cvsroot/openipmi/OpenIPMI/cmdlang/Makefile.am,v
retrieving revision 1.20
diff -u -r1.20 Makefile.am
--- Makefile.am 7 Feb 2006 01:03:35 -0000 1.20
+++ Makefile.am 10 Feb 2006 03:59:16 -0000
@@ -10,7 +10,7 @@
VERSION_AGE = $(wordlist 2, 2, $(SPACE_VERSION))
LD_VERSION = $(VERSION_CURRENT):$(VERSION_REVISION):$(VERSION_AGE)
-AM_CFLAGS = -Wall -I$(top_srcdir)/include -DIPMI_CHECK_LOCKS $(GLIB_CFLAGS)
+AM_CFLAGS = -Wall -I$(top_srcdir)/include -I$(top_srcdir)/libedit/src -DIPMI_CHECK_LOCKS $(GLIB_CFLAGS)
lib_LTLIBRARIES = libOpenIPMIcmdlang.la
@@ -30,6 +30,7 @@
$(top_builddir)/utils/libOpenIPMIutils.la \
$(top_builddir)/lib/libOpenIPMI.la \
$(top_builddir)/unix/libOpenIPMIposix.la \
+ $(top_builddir)/libedit/src/libedit.la \
$(SNMPLIBS) $(GLIB_LIB) $(GLIB_LIBS) $(OPENSSLLIBS) \
$(GDBM_LIB)
@@ -38,4 +39,5 @@
# We need to make a link from ipmish to openipmish for backwards
# compatability.
install-data-local:
- $(LN_S) openipmish $(DESTDIR)$(bindir)/ipmish
\ No newline at end of file
+ $(LN_S) openipmish $(DESTDIR)$(bindir)/ipmish
+
Index: ipmish.c
===================================================================
RCS file: /cvsroot/openipmi/OpenIPMI/cmdlang/ipmish.c,v
retrieving revision 1.26
diff -u -r1.26 ipmish.c
--- ipmish.c 10 Jan 2006 22:20:53 -0000 1.26
+++ ipmish.c 10 Feb 2006 03:59:17 -0000
@@ -47,6 +47,7 @@
#include <OpenIPMI/ipmi_glib.h>
#include <OpenIPMI/ipmi_cmdlang.h>
#include <OpenIPMI/ipmi_debug.h>
+#include <editline/readline.h>
#ifdef HAVE_GLIB
#include <glib.h>
@@ -78,9 +79,6 @@
static int done = 0;
static int evcount = 0;
static int handling_input = 0;
-static char *line_buffer;
-static int line_buffer_max = 0;
-static int line_buffer_pos = 0;
static int cmd_redisp = 1;
static void user_input_ready(int fd, void *data, os_hnd_fd_id_t *id);
@@ -93,8 +91,7 @@
if (force)
redisp = 1;
if (!done && handling_input && redisp) {
- fputs("> ", stdout);
- fwrite(line_buffer, 1, line_buffer_pos, stdout);
+ rl_redisplay();
fflush(stdout);
}
}
@@ -607,105 +604,41 @@
static void
user_input_ready(int fd, void *data, os_hnd_fd_id_t *id)
{
- ipmi_cmdlang_t *info = data;
- out_data_t *out_data = info->user_data;
- char rc;
- int count;
- int i;
+ rl_callback_read_char();
+}
+
+static void
+rl_ipmish_cb_handler(char *cmdline)
+{
+ char *expansion = NULL;
+ int result;
- count = read(fd, &rc, 1);
- if (count <= 0) {
+ if (cmdline == NULL) {
done = 1;
evcount = 1; /* Force a newline */
return;
}
-
- switch(rc) {
- case 0x04: /* ^d */
- if (line_buffer_pos == 0) {
- done = 1;
- evcount = 1; /* Force a newline */
- }
- break;
-
- case 12: /* ^l */
- fputc('\n', out_data->stream);
- redraw_cmdline(1);
- break;
-
- case '\r': case '\n':
- fputc(rc, out_data->stream);
- if (line_buffer) {
- line_buffer[line_buffer_pos] = '\0';
- for (i=0; isspace(line_buffer[i]); i++)
- ;
- /* Ignore blank lines. */
- if (line_buffer[i] != '\0') {
- /* Turn off input processing. */
- disable_term_fd(info);
-
- cmdlang.err = 0;
- cmdlang.errstr = NULL;
- cmdlang.errstr_dynalloc = 0;
- cmdlang.location = NULL;
- handling_input = 0;
- line_buffer_pos = 0;
- ipmi_cmdlang_handle(&cmdlang, line_buffer);
- } else {
- fputs("> ", out_data->stream);
- }
- } else {
- fputs("> ", out_data->stream);
- }
- break;
-
- case 0x7f: /* delete */
- case '\b': /* backspace */
- if (line_buffer_pos > 0) {
- line_buffer_pos--;
- fputs("\b \b", out_data->stream);
- }
- break;
-
- default:
- if (line_buffer_pos >= line_buffer_max) {
- char *new_line = ipmi_mem_alloc(line_buffer_max+10+1);
- if (!new_line)
- break;
- line_buffer_max += 10;
- if (line_buffer) {
- memcpy(new_line, line_buffer, line_buffer_pos);
- ipmi_mem_free(line_buffer);
- }
- line_buffer = new_line;
- }
- line_buffer[line_buffer_pos] = rc;
- line_buffer_pos++;
- fputc(rc, out_data->stream);
- break;
+ result = history_expand(cmdline, &expansion);
+ if (result < 0 || result == 2) {
+ fprintf(stderr, "%s\n", expansion);
+ } else if (expansion && strlen(expansion)){
+ cmdlang.err = 0;
+ cmdlang.errstr = NULL;
+ cmdlang.errstr_dynalloc = 0;
+ cmdlang.location = NULL;
+ handling_input = 0;
+ add_history(expansion);
+ ipmi_cmdlang_handle(&cmdlang, expansion);
}
-
- fflush(out_data->stream);
+ if (expansion)
+ ipmi_mem_free(expansion);
}
-static int term_setup;
-struct termios old_termios;
-
static void
cleanup_term(void)
{
- if (line_buffer) {
- ipmi_mem_free(line_buffer);
- line_buffer = NULL;
- }
+ rl_callback_handler_remove();
disable_term_fd(&cmdlang);
-
- if (!term_setup)
- return;
-
- tcsetattr(0, TCSADRAIN, &old_termios);
- tcdrain(0);
- term_setup = 0;
}
static void cleanup_sig(int sig);
@@ -713,20 +646,14 @@
static void
setup_term(os_handler_t *os_hnd)
{
- struct termios new_termios;
-
- tcgetattr(0, &old_termios);
- new_termios = old_termios;
- new_termios.c_lflag &= ~(ICANON|ECHO);
- tcsetattr(0, TCSADRAIN, &new_termios);
- term_setup = 1;
-
signal(SIGINT, cleanup_sig);
signal(SIGPIPE, cleanup_sig);
signal(SIGUSR1, cleanup_sig);
signal(SIGUSR2, cleanup_sig);
signal(SIGPWR, cleanup_sig);
+ stifle_history(500);
+ rl_callback_handler_install("> ", rl_ipmish_cb_handler);
lout_data.stream = stdout;
cmdlang.os_hnd = os_hnd;
@@ -809,6 +736,7 @@
read_nest++;
saved_done_ptr = done_ptr;
+ /* not record the file's commands into history */
while (fgets(cmdline, sizeof(cmdline), s)) {
my_out_data.stream = stdout;
my_out_data.indent = 0;
@@ -816,6 +744,7 @@
cdone = 0;
done_ptr = &cdone;
printf("> %s", cmdline);
+ fflush(stdout);
ipmi_cmdlang_handle(&my_cmdlang, cmdline);
while (!cdone)
cmdlang->os_hnd->perform_one_op(cmdlang->os_hnd, NULL);
@@ -1097,8 +1026,9 @@
read_nest = 1;
execs = e->next;
printf("> %s\n", e->str);
+ fflush(stdout);
done_ptr = &cdone;
- ipmi_cmdlang_handle(&cmdlang, e->str);
+ rl_ipmish_cb_handler(e->str);
while (!cdone)
os_hnd->perform_one_op(os_hnd, NULL);
done_ptr = NULL;
@@ -1106,7 +1036,6 @@
read_nest = 0;
}
- printf("> ");
fflush(stdout);
handling_input = 1;
@@ -1131,8 +1060,11 @@
os_hnd->free_os_handler(os_hnd);
+ /* remove the prompt which editline printed */
+ printf("\b\b \b\b");
if (evcount)
printf("\n");
+ fflush(stdout);
if (rv)
return 1;
