diff -ruN sash-3.6/Makefile sash-3.6.readline/Makefile
--- sash-3.6/Makefile 2003-10-17 14:25:00.306848712 +0200
+++ sash-3.6.readline/Makefile 2003-10-17 14:27:34.529403320 +0200
@@ -19,10 +19,11 @@
-DHAVE_LINUX_ATTR=$(HAVE_LINUX_ATTR) \
-DHAVE_LINUX_MOUNT=$(HAVE_LINUX_MOUNT) \
-DHAVE_BSD_MOUNT=$(HAVE_BSD_MOUNT) \
- -DMOUNT_TYPE=$(MOUNT_TYPE)
+ -DMOUNT_TYPE=$(MOUNT_TYPE) \
+ -DHAVE_READLINE
LDFLAGS = --disable-shared -static -s
-LIBS = -lz
+LIBS = -lz -lreadline -lncurses
BINDIR = /bin
diff -ruN sash-3.6/sash.c sash-3.6.readline/sash.c
--- sash-3.6/sash.c 2002-07-22 00:55:28.000000000 +0200
+++ sash-3.6.readline/sash.c 2003-10-17 14:26:26.184793280 +0200
@@ -384,6 +384,201 @@
static void usage(void);
static Alias * findAlias(const char * name);
+#ifdef HAVE_READLINE
+/*--- Interface of readline 4.0 by vlk@vinf.ru ---*/
+
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <dirent.h>
+
+char * dupstr (char *s);
+void initialize_readline (void);
+char ** fileman_completion (char *text, int start, int end);
+char *command_generator (char *text, int state);
+void err_alloc(int ErrorNumber);
+extern char *xmalloc ();
+
+static char ** listBase;
+static long listSize;
+
+void
+err_alloc(int ErrorNumber)
+{
+ fprintf(stderr, "Memory space failed: %d\n",ErrorNumber);
+ return;
+}
+
+/* Add a one item to exec-command array */
+static int
+listAdd(const char * new_item)
+{
+ if ((listBase = realloc(listBase, sizeof(char *) * ( listSize + 1 ))) == 0 )
+ {
+ err_alloc(3); exit(1);
+ }
+ listBase[listSize] = strdup(new_item);
+ listSize++;
+ return(0);
+}
+
+static int
+genExecList(void)
+{
+ char * dirName;
+ char * path;
+ char * endPath;
+ char * fullName;
+ struct dirent **namelist;
+ int n;
+
+ if (getenv("PATH") == 0)
+ return(1);
+ else
+ {
+ if ((path = strdup(getenv("PATH"))) == 0)
+ {
+ err_alloc(4);
+ return(1);
+ }
+ }
+ /*
+ * Check out each path to see if the program exists and is
+ * executable in that path.
+ */
+ for ( ; path; path = endPath)
+ {
+ /*
+ * Find the end of the next path and NULL terminate
+ * it if necessary.
+ */
+ endPath = strchr(path, ':');
+
+ if (endPath)
+ *endPath++ = '\0';
+
+ /*
+ * Get the directory name, defaulting it to DOT if
+ * it is null.
+ */
+ dirName = path;
+
+ /*
+ * See if the program exists and is executable.
+ */
+ if (access(dirName, F_OK) < 0)
+ {
+ if (errno != ENOENT)
+ printf("%s: %s\n", dirName, strerror(errno));
+
+ continue;
+ }
+ n = scandir(dirName, &namelist, 0, alphasort);
+ if (n < 0)
+ perror("scandir");
+ else
+ while(n--)
+ {
+ if (strncmp(namelist[n]->d_name,".",1) != 0)
+ {
+ fullName = malloc(sizeof(dirName) + 1 \
+ + sizeof(namelist[n]->d_name));
+ strcpy(fullName, dirName);
+ strcat(fullName, "/");
+ strcat(fullName, namelist[n]->d_name);
+ if (access(fullName,X_OK|F_OK) == 0)
+ listAdd(namelist[n]->d_name);
+ }
+ }
+ }
+return(0);
+}
+
+/******************************************************************/
+/* BEGIN Interface to Readline Completion */
+/******************************************************************/
+
+char * dupstr (char *s)
+{
+ char *r;
+
+ r = xmalloc (strlen (s) + 1);
+ strcpy (r, s);
+ return (r);
+}
+
+/* Tell the GNU Readline library how to complete. We want to try to complete
+ on command names if this is the first word in the line, or on filenames
+ if not. */
+void initialize_readline (void)
+{
+ /* Allow conditional parsing of the ~/.inputrc file. */
+ rl_readline_name = "readline";
+
+ /* Tell the completer that we want a crack first. */
+ rl_attempted_completion_function = (CPPFunction *)fileman_completion;
+}
+
+/* Attempt to complete on the contents of TEXT. START and END bound the
+ region of rl_line_buffer that contains the word to complete. TEXT is
+ the word to complete. We can use the entire contents of rl_line_buffer
+ in case we want to do some simple parsing. Return the array of matches,
+ or NULL if there aren't any. */
+char ** fileman_completion (char *text, int start, int end)
+{
+ char **matches;
+
+ matches = (char **)NULL;
+
+ /* If this word is at the start of the line, then it is a command
+ to complete. Otherwise it is the name of a file in the current
+ directory. */
+ if (start == 0) // is it the begin of string ?
+ matches = completion_matches (text, command_generator);
+ return (matches);
+}
+
+/* Generator function for command completion. STATE lets us know whether
+ to start from scratch; without any state (i.e. STATE == 0), then we
+ start at the top of the list. */
+char * command_generator (char *text, int state)
+{
+ static int list_index, len;
+ char *ename;
+ static long exec_count;
+
+ /* If this is a new word to complete, initialize now. This includes
+ saving the length of TEXT for efficiency, and initializing the index
+ variable to 0. */
+ if (!state)
+ {
+ exec_count = 0;
+ list_index = 0;
+ len = strlen (text);
+ }
+
+ /* Return the next name which partially matches from the command list. */
+
+ while (ename = (char*)commandEntryTable[list_index].name)
+ {
+ list_index++;
+ if (strncmp (ename, text, len) == 0)
+ return (dupstr(ename));
+ }
+
+ while (exec_count < listSize)
+ {
+ ename = listBase[exec_count];
+ exec_count++;
+ if (strncmp (ename, text, len) == 0)
+ return(dupstr(ename));
+ }
+ /* If no names matched, then return NULL. */
+ return ((char *)NULL);
+}
+/******************************************************************/
+/* END Interface to Readline Completion */
+/******************************************************************/
+#endif
/*
* Global interrupt flag.
@@ -405,7 +600,16 @@
commandFile = NULL;
quietFlag = FALSE;
aliasFlag = FALSE;
+#ifdef HAVE_READLINE
+ /*
+ * Default our path if it is not set.
+ */
+ if (getenv("PATH") == NULL)
+ putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin");
+ genExecList();
+ initialize_readline (); /* Bind our completer. */
+#endif
/*
* Look for options.
*/
@@ -554,6 +758,9 @@
static void
readFile(const char * name)
{
+#ifdef HAVE_READLINE
+ char *input_line = NULL;
+#endif
FILE * fp;
int cc;
BOOL ttyFlag;
@@ -586,9 +793,10 @@
while (TRUE)
{
- if (ttyFlag)
+#ifndef HAVE_READLINE
+ if (ttyFlag)
showPrompt();
-
+#endif
if (intFlag && !ttyFlag && (fp != stdin))
{
fclose(fp);
@@ -805,17 +805,34 @@
return;
}
- if (fgets(buf, CMD_LEN - 1, fp) == NULL)
+#ifdef HAVE_READLINE
+ if (name != NULL)
{
- if (ferror(fp) && (errno == EINTR))
+#endif
+ if (fgets(buf, CMD_LEN - 1, fp) == NULL)
{
- clearerr(fp);
+ if (ferror(fp) && (errno == EINTR))
+ {
+ clearerr(fp);
+ continue;
+ }
- continue;
+ break;
}
-
- break;
+#ifdef HAVE_READLINE
}
+ if (name == NULL)
+ {
+ input_line = readline(prompt ? prompt : "$ ");
+ if (input_line)
+ {
+ if (*input_line)
+ add_history(input_line);
+ strcpy(buf,input_line);
+ }
+ free(input_line);
+ }
+#endif
cc = strlen(buf);