1/* bashhist.c -- bash interface to the GNU history library. */
2
3/* Copyright (C) 1993-2004 Free Software Foundation, Inc.
4
5   This file is part of GNU Bash, the Bourne Again SHell.
6
7   Bash is free software; you can redistribute it and/or modify it under
8   the terms of the GNU General Public License as published by the Free
9   Software Foundation; either version 2, or (at your option) any later
10   version.
11
12   Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13   WARRANTY; without even the implied warranty of MERCHANTABILITY or
14   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15   for more details.
16
17   You should have received a copy of the GNU General Public License along
18   with Bash; see the file COPYING.  If not, write to the Free Software
19   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
20
21#include "config.h"
22
23#if defined (HISTORY)
24
25#if defined (HAVE_UNISTD_H)
26#  ifdef _MINIX
27#    include <sys/types.h>
28#  endif
29#  include <unistd.h>
30#endif
31
32#include "bashtypes.h"
33#include <stdio.h>
34#include <errno.h>
35#include "bashansi.h"
36#include "posixstat.h"
37#include "filecntl.h"
38
39#include "bashintl.h"
40
41#include "shell.h"
42#include "flags.h"
43#include "input.h"
44#include "parser.h"	/* for the struct dstack stuff. */
45#include "pathexp.h"	/* for the struct ignorevar stuff */
46#include "bashhist.h"	/* matching prototypes and declarations */
47#include "builtins/common.h"
48
49#include <readline/history.h>
50#include <glob/glob.h>
51#include <glob/strmatch.h>
52
53#if defined (READLINE)
54#  include "bashline.h"
55extern int rl_done, rl_dispatching;	/* should really include readline.h */
56#endif
57
58#if !defined (errno)
59extern int errno;
60#endif
61
62static int histignore_item_func __P((struct ign *));
63static int check_history_control __P((char *));
64static void hc_erasedups __P((char *));
65static void really_add_history __P((char *));
66
67static struct ignorevar histignore =
68{
69  "HISTIGNORE",
70  (struct ign *)0,
71  0,
72  (char *)0,
73  (sh_iv_item_func_t *)histignore_item_func,
74};
75
76#define HIGN_EXPAND 0x01
77
78/* Declarations of bash history variables. */
79/* Non-zero means to remember lines typed to the shell on the history
80   list.  This is different than the user-controlled behaviour; this
81   becomes zero when we read lines from a file, for example. */
82int remember_on_history = 1;
83int enable_history_list = 1;	/* value for `set -o history' */
84
85/* The number of lines that Bash has added to this history session.  The
86   difference between the number of the top element in the history list
87   (offset from history_base) and the number of lines in the history file.
88   Appending this session's history to the history file resets this to 0. */
89int history_lines_this_session;
90
91/* The number of lines that Bash has read from the history file. */
92int history_lines_in_file;
93
94#if defined (BANG_HISTORY)
95/* Non-zero means do no history expansion on this line, regardless
96   of what history_expansion says. */
97int history_expansion_inhibited;
98#endif
99
100/* With the old default, every line was saved in the history individually.
101   I.e., if the user enters:
102	bash$ for i in a b c
103	> do
104	> echo $i
105	> done
106   Each line will be individually saved in the history.
107	bash$ history
108	10  for i in a b c
109	11  do
110	12  echo $i
111	13  done
112	14  history
113   If the variable command_oriented_history is set, multiple lines
114   which form one command will be saved as one history entry.
115	bash$ for i in a b c
116	> do
117	> echo $i
118	> done
119	bash$ history
120	10  for i in a b c
121    do
122    echo $i
123    done
124	11  history
125   The user can then recall the whole command all at once instead
126   of just being able to recall one line at a time.
127
128   This is now enabled by default.
129   */
130int command_oriented_history = 1;
131
132/* Set to 1 if the first line of a possibly-multi-line command was saved
133   in the history list.  Managed by maybe_add_history(), but global so
134   the history-manipluating builtins can see it. */
135int current_command_first_line_saved = 0;
136
137/* Non-zero means to store newlines in the history list when using
138   command_oriented_history rather than trying to use semicolons. */
139int literal_history;
140
141/* Non-zero means to append the history to the history file at shell
142   exit, even if the history has been stifled. */
143int force_append_history;
144
145/* A nit for picking at history saving.  Flags have the following values:
146
147   Value == 0 means save all lines parsed by the shell on the history.
148   Value & HC_IGNSPACE means save all lines that do not start with a space.
149   Value & HC_IGNDUPS means save all lines that do not match the last
150   line saved.
151   Value & HC_ERASEDUPS means to remove all other matching lines from the
152   history list before saving the latest line. */
153int history_control;
154
155/* Set to 1 if the last command was added to the history list successfully
156   as a separate history entry; set to 0 if the line was ignored or added
157   to a previous entry as part of command-oriented-history processing. */
158int hist_last_line_added;
159
160/* Set to 1 if builtins/history.def:push_history added the last history
161   entry. */
162int hist_last_line_pushed;
163
164#if defined (READLINE)
165/* If non-zero, and readline is being used, the user is offered the
166   chance to re-edit a failed history expansion. */
167int history_reediting;
168
169/* If non-zero, and readline is being used, don't directly execute a
170   line with history substitution.  Reload it into the editing buffer
171   instead and let the user further edit and confirm with a newline. */
172int hist_verify;
173
174#endif /* READLINE */
175
176/* Non-zero means to not save function definitions in the history list. */
177int dont_save_function_defs;
178
179/* Variables declared in other files used here. */
180extern int current_command_line_count;
181
182extern struct dstack dstack;
183
184static int bash_history_inhibit_expansion __P((char *, int));
185#if defined (READLINE)
186static void re_edit __P((char *));
187#endif
188static int history_expansion_p __P((char *));
189static int shell_comment __P((char *));
190static int should_expand __P((char *));
191static HIST_ENTRY *last_history_entry __P((void));
192static char *expand_histignore_pattern __P((char *));
193static int history_should_ignore __P((char *));
194
195/* Is the history expansion starting at string[i] one that should not
196   be expanded? */
197static int
198bash_history_inhibit_expansion (string, i)
199     char *string;
200     int i;
201{
202  /* The shell uses ! as a pattern negation character in globbing [...]
203     expressions, so let those pass without expansion. */
204  if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
205    return (1);
206  /* The shell uses ! as the indirect expansion character, so let those
207     expansions pass as well. */
208  else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
209	     member ('}', string + i + 1))
210    return (1);
211#if defined (EXTENDED_GLOB)
212  else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
213    return (1);
214#endif
215  else
216    return (0);
217}
218
219void
220bash_initialize_history ()
221{
222  history_quotes_inhibit_expansion = 1;
223  history_search_delimiter_chars = ";&()|<>";
224  history_inhibit_expansion_function = bash_history_inhibit_expansion;
225#if defined (BANG_HISTORY)
226  sv_histchars ("histchars");
227#endif
228}
229
230void
231bash_history_reinit (interact)
232     int interact;
233{
234#if defined (BANG_HISTORY)
235  history_expansion = interact != 0;
236  history_expansion_inhibited = 1;
237#endif
238  remember_on_history = enable_history_list = interact != 0;
239  history_inhibit_expansion_function = bash_history_inhibit_expansion;
240}
241
242void
243bash_history_disable ()
244{
245  remember_on_history = 0;
246#if defined (BANG_HISTORY)
247  history_expansion_inhibited = 1;
248#endif
249}
250
251void
252bash_history_enable ()
253{
254  remember_on_history = 1;
255#if defined (BANG_HISTORY)
256  history_expansion_inhibited = 0;
257#endif
258  history_inhibit_expansion_function = bash_history_inhibit_expansion;
259  sv_history_control ("HISTCONTROL");
260  sv_histignore ("HISTIGNORE");
261}
262
263/* Load the history list from the history file. */
264void
265load_history ()
266{
267  char *hf;
268  struct stat buf;
269
270  /* Truncate history file for interactive shells which desire it.
271     Note that the history file is automatically truncated to the
272     size of HISTSIZE if the user does not explicitly set the size
273     differently. */
274  set_if_not ("HISTSIZE", "500");
275  sv_histsize ("HISTSIZE");
276
277  set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
278  sv_histsize ("HISTFILESIZE");
279
280  /* Read the history in HISTFILE into the history list. */
281  hf = get_string_value ("HISTFILE");
282
283  if (hf && *hf && stat (hf, &buf) == 0)
284    {
285      read_history (hf);
286      using_history ();
287      history_lines_in_file = where_history ();
288    }
289}
290
291#ifdef INCLUDE_UNUSED
292/* Write the existing history out to the history file. */
293void
294save_history ()
295{
296  char *hf;
297  struct stat buf;
298
299  hf = get_string_value ("HISTFILE");
300  if (hf && *hf && stat (hf, &buf) == 0)
301    {
302      /* Append only the lines that occurred this session to
303	 the history file. */
304      using_history ();
305
306      if (history_lines_this_session < where_history () || force_append_history)
307	append_history (history_lines_this_session, hf);
308      else
309	write_history (hf);
310
311      sv_histsize ("HISTFILESIZE");
312    }
313}
314#endif
315
316int
317maybe_append_history (filename)
318     char *filename;
319{
320  int fd, result;
321  struct stat buf;
322
323  result = EXECUTION_SUCCESS;
324  if (history_lines_this_session && (history_lines_this_session < where_history ()))
325    {
326      /* If the filename was supplied, then create it if necessary. */
327      if (stat (filename, &buf) == -1 && errno == ENOENT)
328	{
329	  fd = open (filename, O_WRONLY|O_CREAT, 0600);
330	  if (fd < 0)
331	    {
332	      builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
333	      return (EXECUTION_FAILURE);
334	    }
335	  close (fd);
336	}
337      result = append_history (history_lines_this_session, filename);
338      history_lines_in_file += history_lines_this_session;
339      history_lines_this_session = 0;
340    }
341  return (result);
342}
343
344/* If this is an interactive shell, then append the lines executed
345   this session to the history file. */
346int
347maybe_save_shell_history ()
348{
349  int result;
350  char *hf;
351  struct stat buf;
352
353  result = 0;
354  if (history_lines_this_session)
355    {
356      hf = get_string_value ("HISTFILE");
357
358      if (hf && *hf)
359	{
360	  /* If the file doesn't exist, then create it. */
361	  if (stat (hf, &buf) == -1)
362	    {
363	      int file;
364	      file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
365	      if (file != -1)
366		close (file);
367	    }
368
369	  /* Now actually append the lines if the history hasn't been
370	     stifled.  If the history has been stifled, rewrite the
371	     history file. */
372	  using_history ();
373	  if (history_lines_this_session <= where_history () || force_append_history)
374	    {
375	      result = append_history (history_lines_this_session, hf);
376	      history_lines_in_file += history_lines_this_session;
377	    }
378	  else
379	    {
380	      result = write_history (hf);
381	      history_lines_in_file = history_lines_this_session;
382	    }
383	  history_lines_this_session = 0;
384
385	  sv_histsize ("HISTFILESIZE");
386	}
387    }
388  return (result);
389}
390
391#if defined (READLINE)
392/* Tell readline () that we have some text for it to edit. */
393static void
394re_edit (text)
395     char *text;
396{
397  if (bash_input.type == st_stdin)
398    bash_re_edit (text);
399}
400#endif /* READLINE */
401
402/* Return 1 if this line needs history expansion. */
403static int
404history_expansion_p (line)
405     char *line;
406{
407  register char *s;
408
409  for (s = line; *s; s++)
410    if (*s == history_expansion_char || *s == history_subst_char)
411      return 1;
412  return 0;
413}
414
415/* Do pre-processing on LINE.  If PRINT_CHANGES is non-zero, then
416   print the results of expanding the line if there were any changes.
417   If there is an error, return NULL, otherwise the expanded line is
418   returned.  If ADDIT is non-zero the line is added to the history
419   list after history expansion.  ADDIT is just a suggestion;
420   REMEMBER_ON_HISTORY can veto, and does.
421   Right now this does history expansion. */
422char *
423pre_process_line (line, print_changes, addit)
424     char *line;
425     int print_changes, addit;
426{
427  char *history_value;
428  char *return_value;
429  int expanded;
430
431  return_value = line;
432  expanded = 0;
433
434#  if defined (BANG_HISTORY)
435  /* History expand the line.  If this results in no errors, then
436     add that line to the history if ADDIT is non-zero. */
437  if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
438    {
439      expanded = history_expand (line, &history_value);
440
441      if (expanded)
442	{
443	  if (print_changes)
444	    {
445	      if (expanded < 0)
446		internal_error ("%s", history_value);
447#if defined (READLINE)
448	      else if (hist_verify == 0 || expanded == 2)
449#else
450	      else
451#endif
452		fprintf (stderr, "%s\n", history_value);
453	    }
454
455	  /* If there was an error, return NULL. */
456	  if (expanded < 0 || expanded == 2)	/* 2 == print only */
457	    {
458#    if defined (READLINE)
459	      if (expanded == 2 && rl_dispatching == 0 && *history_value)
460#    else
461	      if (expanded == 2 && *history_value)
462#    endif /* !READLINE */
463		maybe_add_history (history_value);
464
465	      free (history_value);
466
467#    if defined (READLINE)
468	      /* New hack.  We can allow the user to edit the
469		 failed history expansion. */
470	      if (history_reediting && expanded < 0 && rl_done)
471		re_edit (line);
472#    endif /* READLINE */
473	      return ((char *)NULL);
474	    }
475
476#    if defined (READLINE)
477	  if (hist_verify && expanded == 1)
478	    {
479	      re_edit (history_value);
480	      return ((char *)NULL);
481	    }
482#    endif
483	}
484
485      /* Let other expansions know that return_value can be free'ed,
486	 and that a line has been added to the history list.  Note
487	 that we only add lines that have something in them. */
488      expanded = 1;
489      return_value = history_value;
490    }
491#  endif /* BANG_HISTORY */
492
493  if (addit && remember_on_history && *return_value)
494    maybe_add_history (return_value);
495
496#if 0
497  if (expanded == 0)
498    return_value = savestring (line);
499#endif
500
501  return (return_value);
502}
503
504/* Return 1 if the first non-whitespace character in LINE is a `#', indicating
505 * that the line is a shell comment. */
506static int
507shell_comment (line)
508     char *line;
509{
510  char *p;
511
512  for (p = line; p && *p && whitespace (*p); p++)
513    ;
514  return (p && *p == '#');
515}
516
517#ifdef INCLUDE_UNUSED
518/* Remove shell comments from LINE.  A `#' and anything after it is a comment.
519   This isn't really useful yet, since it doesn't handle quoting. */
520static char *
521filter_comments (line)
522     char *line;
523{
524  char *p;
525
526  for (p = line; p && *p && *p != '#'; p++)
527    ;
528  if (p && *p == '#')
529    *p = '\0';
530  return (line);
531}
532#endif
533
534/* Check LINE against what HISTCONTROL says to do.  Returns 1 if the line
535   should be saved; 0 if it should be discarded. */
536static int
537check_history_control (line)
538     char *line;
539{
540  HIST_ENTRY *temp;
541  int r;
542
543  if (history_control == 0)
544    return 1;
545
546  /* ignorespace or ignoreboth */
547  if ((history_control & HC_IGNSPACE) && *line == ' ')
548    return 0;
549
550  /* ignoredups or ignoreboth */
551  if (history_control & HC_IGNDUPS)
552    {
553      using_history ();
554      temp = previous_history ();
555
556      r = (temp == 0 || STREQ (temp->line, line) == 0);
557
558      using_history ();
559
560      if (r == 0)
561	return r;
562    }
563
564  return 1;
565}
566
567/* Remove all entries matching LINE from the history list.  Triggered when
568   HISTCONTROL includes `erasedups'. */
569static void
570hc_erasedups (line)
571     char *line;
572{
573  HIST_ENTRY *temp;
574  int r;
575
576  using_history ();
577  while (temp = previous_history ())
578    {
579      if (STREQ (temp->line, line))
580	{
581	  r = where_history ();
582	  remove_history (r);
583	}
584    }
585  using_history ();
586}
587
588/* Add LINE to the history list, handling possibly multi-line compound
589   commands.  We note whether or not we save the first line of each command
590   (which is usually the entire command and history entry), and don't add
591   the second and subsequent lines of a multi-line compound command if we
592   didn't save the first line.  We don't usually save shell comment lines in
593   compound commands in the history, because they could have the effect of
594   commenting out the rest of the command when the entire command is saved as
595   a single history entry (when COMMAND_ORIENTED_HISTORY is enabled).  If
596   LITERAL_HISTORY is set, we're saving lines in the history with embedded
597   newlines, so it's OK to save comment lines.  We also make sure to save
598   multiple-line quoted strings or other constructs. */
599void
600maybe_add_history (line)
601     char *line;
602{
603  hist_last_line_added = 0;
604
605  /* Don't use the value of history_control to affect the second
606     and subsequent lines of a multi-line command (old code did
607     this only when command_oriented_history is enabled). */
608  if (current_command_line_count > 1)
609    {
610      if (current_command_first_line_saved &&
611	  (literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
612	bash_add_history (line);
613      return;
614    }
615
616  /* This is the first line of a (possible multi-line) command.  Note whether
617     or not we should save the first line and remember it. */
618  current_command_first_line_saved = check_add_history (line, 0);
619}
620
621/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
622   history if it's OK.  Used by `history -s' as well as maybe_add_history().
623   Returns 1 if the line was saved in the history, 0 otherwise. */
624int
625check_add_history (line, force)
626     char *line;
627     int force;
628{
629  if (check_history_control (line) && history_should_ignore (line) == 0)
630    {
631      /* We're committed to saving the line.  If the user has requested it,
632	 remove other matching lines from the history. */
633      if (history_control & HC_ERASEDUPS)
634	hc_erasedups (line);
635
636      if (force)
637	{
638	  really_add_history (line);
639	  using_history ();
640	}
641      else
642	bash_add_history (line);
643      return 1;
644    }
645  return 0;
646}
647
648/* Add a line to the history list.
649   The variable COMMAND_ORIENTED_HISTORY controls the style of history
650   remembering;  when non-zero, and LINE is not the first line of a
651   complete parser construct, append LINE to the last history line instead
652   of adding it as a new line. */
653void
654bash_add_history (line)
655     char *line;
656{
657  int add_it, offset, curlen;
658  HIST_ENTRY *current, *old;
659  char *chars_to_add, *new_line;
660
661  add_it = 1;
662  if (command_oriented_history && current_command_line_count > 1)
663    {
664      chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
665
666      using_history ();
667      current = previous_history ();
668
669      if (current)
670	{
671	  /* If the previous line ended with an escaped newline (escaped
672	     with backslash, but otherwise unquoted), then remove the quoted
673	     newline, since that is what happens when the line is parsed. */
674	  curlen = strlen (current->line);
675
676	  if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
677	      current->line[curlen - 2] != '\\')
678	    {
679	      current->line[curlen - 1] = '\0';
680	      curlen--;
681	      chars_to_add = "";
682	    }
683
684	  new_line = (char *)xmalloc (1
685				      + curlen
686				      + strlen (line)
687				      + strlen (chars_to_add));
688	  sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
689	  offset = where_history ();
690	  old = replace_history_entry (offset, new_line, current->data);
691	  free (new_line);
692
693	  if (old)
694	    free_history_entry (old);
695
696	  add_it = 0;
697	}
698    }
699
700  if (add_it)
701    really_add_history (line);
702
703  using_history ();
704}
705
706static void
707really_add_history (line)
708     char *line;
709{
710  hist_last_line_added = 1;
711  hist_last_line_pushed = 0;
712  add_history (line);
713  history_lines_this_session++;
714}
715
716int
717history_number ()
718{
719  using_history ();
720  return (remember_on_history ? history_base + where_history () : 1);
721}
722
723static int
724should_expand (s)
725     char *s;
726{
727  char *p;
728
729  for (p = s; p && *p; p++)
730    {
731      if (*p == '\\')
732	p++;
733      else if (*p == '&')
734	return 1;
735    }
736  return 0;
737}
738
739static int
740histignore_item_func (ign)
741     struct ign *ign;
742{
743  if (should_expand (ign->val))
744    ign->flags |= HIGN_EXPAND;
745  return (0);
746}
747
748void
749setup_history_ignore (varname)
750     char *varname;
751{
752  setup_ignore_patterns (&histignore);
753}
754
755static HIST_ENTRY *
756last_history_entry ()
757{
758  HIST_ENTRY *he;
759
760  using_history ();
761  he = previous_history ();
762  using_history ();
763  return he;
764}
765
766char *
767last_history_line ()
768{
769  HIST_ENTRY *he;
770
771  he = last_history_entry ();
772  if (he == 0)
773    return ((char *)NULL);
774  return he->line;
775}
776
777static char *
778expand_histignore_pattern (pat)
779     char *pat;
780{
781  HIST_ENTRY *phe;
782  char *ret;
783
784  phe = last_history_entry ();
785
786  if (phe == (HIST_ENTRY *)0)
787    return (savestring (pat));
788
789  ret = strcreplace (pat, '&', phe->line, 1);
790
791  return ret;
792}
793
794/* Return 1 if we should not put LINE into the history according to the
795   patterns in HISTIGNORE. */
796static int
797history_should_ignore (line)
798     char *line;
799{
800  register int i, match;
801  char *npat;
802
803  if (histignore.num_ignores == 0)
804    return 0;
805
806  for (i = match = 0; i < histignore.num_ignores; i++)
807    {
808      if (histignore.ignores[i].flags & HIGN_EXPAND)
809	npat = expand_histignore_pattern (histignore.ignores[i].val);
810      else
811	npat = histignore.ignores[i].val;
812
813      match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
814
815      if (histignore.ignores[i].flags & HIGN_EXPAND)
816	free (npat);
817
818      if (match)
819	break;
820    }
821
822  return match;
823}
824#endif /* HISTORY */
825