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