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