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