[PATCH] Add nofirstword completion option

2018-05-18 Thread Luca Boccassi
Network operating systems traditionally have provided a command
line interface with "operation mode" and "configuration mode", with
different auto-completion behaviour - specifically, with a small set
of supported commands that are printed using the auto-completion
shortcut key, depending on the mode.
In order to be able to implement such modes using Bash, Linux and Free
Software, it's necessary to be able to optionally disable
auto-completion on the first word, so that the relevant help text
(depending on the mode) can be printed on the console instead.
Add and document a nofirstword completion option to implement this
feature.

Signed-off-by: Luca Boccassi 
---
 bashline.c| 47 +++
 builtins/complete.def |  4 
 doc/bash.1|  4 
 doc/bash.html |  5 +
 doc/bash.info |  5 +
 doc/bashref.html  |  5 +
 doc/bashref.info  |  5 +
 pcomplete.h   |  1 +
 8 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/bashline.c b/bashline.c
index ae8fe1cc..436bf8d3 100644
--- a/bashline.c
+++ b/bashline.c
@@ -1313,8 +1313,9 @@ static int
 find_cmd_start (start)
  int start;
 {
-  register int s, os, ns;
+  register int s, os, ns, last;
 
+  last = 0;
   os = 0;
   /* Flags == SD_NOJMP only because we want to skip over command substitutions
  in assignment statements.  Have to test whether this affects `standalone'
@@ -1332,7 +1333,13 @@ find_cmd_start (start)
  continue;
}
   os = s+1;
+  last = s;
 }
+  /* If the last seperator is a pipe keep it at the beginning of the command. 
The
+ pipe character is a command seperator and a command. */
+  if (rl_line_buffer[last] == '|')
+os = last;
+
   return os;
 }
 
@@ -1352,13 +1359,18 @@ find_cmd_name (start, sp, ep)
  int *sp, *ep;
 {
   char *name;
-  register int s, e;
+  register int s, s1, e;
 
   for (s = start; whitespace (rl_line_buffer[s]); s++)
 ;
 
+  /* If first character is a pipe char scan from next char */
+  s1 = s;
+  if (rl_line_buffer[s] == '|')
+++s1;
+
   /* skip until a shell break character */
-  e = skip_to_delim (rl_line_buffer, s, "()<>;&| \t\n", SD_NOJMP|SD_COMPLETE);
+  e = skip_to_delim (rl_line_buffer, s1, "()<>;&| \t\n", SD_NOJMP|SD_COMPLETE);
 
   name = substring (rl_line_buffer, s, e);
 
@@ -1425,6 +1437,7 @@ attempt_shell_completion (text, start, end)
   int in_command_position, ti, qc, dflags;
   char **matches, *command_separator_chars;
 #if defined (PROGRAMMABLE_COMPLETION)
+  COMPSPEC *cs;
   int have_progcomps, was_assignment;
 #endif
 
@@ -1484,6 +1497,11 @@ attempt_shell_completion (text, start, end)
 that all of the previous words on the line are variable
 assignments. */
 }
+#if defined (PROGRAMMABLE_COMPLETION)
+  cs = progcomp_search(DEFAULTCMD);
+  if (cs && cs->options & COPT_NOFIRSTWORD)
+in_command_position = 0;
+#endif /* PROGRAMMABLE_COMPLETION */
 
   if (in_command_position && invalid_completion (text, ti))
 {
@@ -1571,12 +1589,20 @@ attempt_shell_completion (text, start, end)
{
  /* not assignment statement, but still want to perform command
 completion if we are composing command word. */
- foundcs = 0;
- in_command_position = s == start && STREQ (n, text);  /* XXX */
+ if (cs && cs->options & COPT_NOFIRSTWORD)
+   prog_complete_matches = programmable_completions (EMPTYCMD, text, 
s, e, &foundcs);
+ else
+   {
+ foundcs = 0;
+ in_command_position = s == start && STREQ (n, text);  /* XXX 
*/
+   }
}
   else if (e > s && was_assignment == 0 && have_progcomps)
{
- prog_complete_matches = programmable_completions (n, text, s, e, 
&foundcs);
+  if (n[0] == '|' && cs && cs->options & COPT_NOFIRSTWORD)
+prog_complete_matches = programmable_completions (EMPTYCMD, text, 
s, e, &foundcs);
+  else
+prog_complete_matches = programmable_completions (n, text, s, e, 
&foundcs);
  /* command completion if programmable completion fails */
  in_command_position = s == start && STREQ (n, text);  /* XXX */
}
@@ -1584,8 +1610,13 @@ attempt_shell_completion (text, start, end)
   else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0 &&
was_assignment == 0 && member (rl_line_buffer[start-1], 
COMMAND_SEPARATORS))
{
- foundcs = 0;
- in_command_position = 1;
+  if (cs && cs->options & COPT_NOFIRSTWORD)
+prog_complete_matches = programmable_completions (EMPTYCMD, text, 
s, e, &foundcs);
+  else
+{
+ foundcs = 0;  /* empty command name following assignments */
+  in_command_position = was_assignment;
+}
}
   else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0)
 {
diff --git a/b

[PATCH] Add shopt to enable writing history to syslog at runtime

2018-05-18 Thread Luca Boccassi
Currently writing history to syslog can be enabled at compile time by
editing config-top.h and rebuilding.
To allow more flexibility, and to allow users of distributions to
enable this feature at runtime without having to rebuild bash, add a
"syslog" shopt.
To maintain backward compatibility keep using SYSLOG_HISTORY as before
to enable logging to syslog unconditionally.

Signed-off-by: Luca Boccassi 
---
 bashhist.c | 27 +++
 builtins/shopt.def | 11 +++
 doc/bash.0 |  3 +++
 doc/bash.1 |  5 +
 doc/bash.html  |  6 ++
 doc/bash.info  |  5 +
 doc/bashref.html   |  6 ++
 doc/bashref.info   |  5 +
 doc/builtins.0 |  3 +++
 9 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/bashhist.c b/bashhist.c
index 4cf0e4f9..2a5cf35a 100644
--- a/bashhist.c
+++ b/bashhist.c
@@ -38,7 +38,7 @@
 
 #include "bashintl.h"
 
-#if defined (SYSLOG_HISTORY)
+#if defined (HAVE_SYSLOG)
 #  include 
 #endif
 
@@ -773,12 +773,27 @@ check_add_history (line, force)
   return 0;
 }
 
-#if defined (SYSLOG_HISTORY)
+#if defined (HAVE_SYSLOG)
 #define SYSLOG_MAXLEN 600
 
 #ifndef OPENLOG_OPTS
+/* Backward compatibility: leave _OPTS to 0 if not defined in config-tops.h
+   with SYSLOG_HISTORY. */
+#ifdef SYSLOG_HISTORY
 #define OPENLOG_OPTS 0
+#else
+#define OPENLOG_OPTS LOG_PID
 #endif
+#endif
+
+#ifndef SYSLOG_FACILITY
+#define SYSLOG_FACILITY LOG_USER
+#endif
+#ifndef SYSLOG_LEVEL
+#define SYSLOG_LEVEL LOG_INFO
+#endif
+
+int syslog_history_enabled = 0;
 
 void
 bash_syslog_history (line)
@@ -882,8 +897,12 @@ bash_add_history (line)
   if (add_it)
 really_add_history (line);
 
-#if defined (SYSLOG_HISTORY)
-  bash_syslog_history (line);
+#if defined (HAVE_SYSLOG)
+/* Backward compatibility: SYSLOG_HISTORY always enables syslog. */
+#if !defined (SYSLOG_HISTORY)
+  if (syslog_history_enabled)
+#endif
+bash_syslog_history (line);
 #endif
 
   using_history ();
diff --git a/builtins/shopt.def b/builtins/shopt.def
index 467dc534..8340353a 100644
--- a/builtins/shopt.def
+++ b/builtins/shopt.def
@@ -121,6 +121,10 @@ extern int assoc_expand_once;
 extern int array_expand_once;
 #endif
 
+#if defined (HAVE_SYSLOG)
+extern int syslog_history_enabled;
+#endif
+
 static void shopt_error __P((char *));
 
 static int set_shellopts_after_change __P((char *, int));
@@ -236,6 +240,9 @@ static struct {
   { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
   { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
   { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
+#if defined (HAVE_SYSLOG)
+  { "syslog", &syslog_history_enabled, (shopt_set_func_t *)NULL },
+#endif
   { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
 };
 
@@ -381,6 +388,10 @@ reset_shopt_options ()
   xpg_echo = 0;
 #endif /* DEFAULT_ECHO_TO_XPG */
 
+#if defined (HAVE_SYSLOG)
+  syslog_history_enabled = 0;
+#endif
+
   shopt_login_shell = login_shell;
 }
 
diff --git a/doc/bash.0 b/doc/bash.0
index bb2f7429..afceb443 100644
--- a/doc/bash.0
+++ b/doc/bash.0
@@ -5741,6 +5741,9 @@ SSHHEELLLL BBUUIILLTTIINN 
CCOOMMMMAANNDDSS
   If set, the ssoouurrccee (..) builtin uses the 
value of PPAATTHH to
   find  the  directory  containing the file supplied as an
   argument.  This option is enabled by default.
+  ssyysslloogg  If set, the history will be sent to syslog 
with facility
+  LLOOGG__UUSSEERR and level 
LLOOGG__IINNFFOO.  This option is disabled by
+  default.
   xxppgg__eecchhoo
   If  set,  the  eecchhoo  builtin  expands   
backslash-escape
   sequences by default.
diff --git a/doc/bash.1 b/doc/bash.1
index cf712fe3..f19432ff 100644
--- a/doc/bash.1
+++ b/doc/bash.1
@@ -10152,6 +10152,11 @@ If set, the
 to find the directory containing the file supplied as an argument.
 This option is enabled by default.
 .TP 8
+.B syslog
+If set, the history will be sent to syslog with facility
+\fBLOG_USER\fP and level \fBLOG_INFO\fP.
+This option is disabled by default.
+.TP 8
 .B xpg_echo
 If set, the \fBecho\fP builtin expands backslash-escape sequences
 by default.
diff --git a/doc/bash.html b/doc/bash.html
index 54b42fec..574db317 100644
--- a/doc/bash.html
+++ b/doc/bash.html
@@ -12869,6 +12869,12 @@ If set, the
 
 to find the directory containing the file supplied as an argument.
 This option is enabled by default.
+syslog
+
+
+If set, the history will be sent to syslog with facility
+LOG_USER and level LOG_INFO.
+This option is disabled by default.
 xpg_echo
 
 
diff --git a/doc/bash.info b/doc/bash.info
index 9a4edb08..1cef4bfd 100644
--- a/doc/bash.info
+++ b/doc/bash.info
@@ -4667,6 +4667,11 @@ This builtin allows you to change additional shell 
optional behavior.
   the directory containing the file supplied as an argumen

Documentation error

2018-05-18 Thread Jorge Maldonado Ventura
> After the string is decoded, it is expanded via parameter expansion,
command substitution, arithmetic expansion, and quote removal, subject
to the value of the |promptvars| shell option (see _Bash Builtins_).

The documentation should point to the *The Set Builtin*, which is the
section that covers the shell options, not Bash Builtins.