| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | This file is history.def, from which is created history.c. | 
					
						
							|  |  |  | It implements the builtin "history" in Bash. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | Copyright (C) 1987-2016 Free Software Foundation, Inc. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Bash is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  | the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | (at your option) any later version. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | Bash is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | along with Bash.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | $PRODUCES history.c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $BUILTIN history | 
					
						
							|  |  |  | $FUNCTION history_builtin | 
					
						
							|  |  |  | $DEPENDS_ON HISTORY | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | $SHORT_DOC history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...] | 
					
						
							|  |  |  | Display or manipulate the history list. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Display the history list with line numbers, prefixing each modified | 
					
						
							|  |  |  | entry with a `*'.  An argument of N lists only the last N entries. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Options: | 
					
						
							|  |  |  |   -c	clear the history list by deleting all of the entries | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  |   -d offset	delete the history entry at position OFFSET. | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   -a	append history lines from this session to the history file | 
					
						
							|  |  |  |   -n	read all history lines not already read from the history file | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | 		and append them to the history list | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   -r	read the history file and append the contents to the history | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | 		list | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   -w	write the current history to the history file | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   -p	perform history expansion on each ARG and display the result | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | 		without storing it in the history list | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   -s	append the ARGs to the history list as a single entry | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If FILENAME is given, it is used as the history file.  Otherwise, | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | if HISTFILE has a value, that is used, else ~/.bash_history. | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | If the HISTTIMEFORMAT variable is set and not null, its value is used | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | as a format string for strftime(3) to print the time stamp associated | 
					
						
							|  |  |  | with each displayed history entry.  No time stamps are printed otherwise. | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Exit Status: | 
					
						
							|  |  |  | Returns success unless an invalid option is given or an error occurs. | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | $END | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include <config.h> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #if defined (HISTORY) | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #include "../bashtypes.h" | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) | 
					
						
							| 
									
										
										
										
											1998-04-17 19:52:44 +00:00
										 |  |  | #  include <sys/file.h> | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #include "posixstat.h" | 
					
						
							|  |  |  | #include "filecntl.h" | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include <errno.h> | 
					
						
							|  |  |  | #include <stdio.h> | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H) | 
					
						
							|  |  |  | #  include <unistd.h> | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../bashansi.h" | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #include "../bashintl.h" | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "../shell.h" | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #include "../bashhist.h" | 
					
						
							|  |  |  | #include <readline/history.h> | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #include "bashgetopt.h" | 
					
						
							|  |  |  | #include "common.h" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if !defined (errno) | 
					
						
							|  |  |  | extern int errno; | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | extern int current_command_line_count; | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | extern int force_append_history;	/* shopt -s histappend */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | static char *histtime __P((HIST_ENTRY *, const char *)); | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | static int display_history __P((WORD_LIST *)); | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | static void push_history __P((WORD_LIST *)); | 
					
						
							|  |  |  | static int expand_and_print_history __P((WORD_LIST *)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | #define AFLAG	0x01 | 
					
						
							|  |  |  | #define RFLAG	0x02 | 
					
						
							|  |  |  | #define WFLAG	0x04 | 
					
						
							|  |  |  | #define NFLAG	0x08 | 
					
						
							|  |  |  | #define SFLAG	0x10 | 
					
						
							|  |  |  | #define PFLAG	0x20 | 
					
						
							|  |  |  | #define CFLAG	0x40 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #define DFLAG	0x80 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | history_builtin (list) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   int flags, opt, result, old_history_lines, obase; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   char *filename, *delete_arg; | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   intmax_t delete_offset; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   flags = 0; | 
					
						
							|  |  |  |   reset_internal_getopt (); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   while ((opt = internal_getopt (list, "acd:npsrw")) != -1) | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       switch (opt) | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	case 'a': | 
					
						
							|  |  |  | 	  flags |= AFLAG; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	case 'c': | 
					
						
							|  |  |  | 	  flags |= CFLAG; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case 'n': | 
					
						
							|  |  |  | 	  flags |= NFLAG; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case 'r': | 
					
						
							|  |  |  | 	  flags |= RFLAG; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case 'w': | 
					
						
							|  |  |  | 	  flags |= WFLAG; | 
					
						
							|  |  |  | 	  break; | 
					
						
							|  |  |  | 	case 's': | 
					
						
							|  |  |  | 	  flags |= SFLAG; | 
					
						
							|  |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	case 'd': | 
					
						
							|  |  |  | 	  flags |= DFLAG; | 
					
						
							|  |  |  | 	  delete_arg = list_optarg; | 
					
						
							|  |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	case 'p': | 
					
						
							|  |  |  | #if defined (BANG_HISTORY) | 
					
						
							|  |  |  | 	  flags |= PFLAG; | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	  break; | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | 	CASE_HELPOPT; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 	  builtin_usage (); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	  return (EX_USAGE); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   list = loptend; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG); | 
					
						
							|  |  |  |   if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       builtin_error (_("cannot use more than one of -anrw")); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       return (EXECUTION_FAILURE); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* clear the history, but allow other arguments to add to it again. */ | 
					
						
							|  |  |  |   if (flags & CFLAG) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |       bash_clear_history (); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       if (list == 0) | 
					
						
							|  |  |  | 	return (EXECUTION_SUCCESS); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   if (flags & SFLAG) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (list) | 
					
						
							|  |  |  | 	push_history (list); | 
					
						
							|  |  |  |       return (EXECUTION_SUCCESS); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #if defined (BANG_HISTORY) | 
					
						
							|  |  |  |   else if (flags & PFLAG) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (list) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	return (expand_and_print_history (list)); | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |       return (sh_chkwrite (EXECUTION_SUCCESS)); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   else if (flags & DFLAG) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       if ((legal_number (delete_arg, &delete_offset) == 0) | 
					
						
							|  |  |  | 	  || (delete_offset < history_base) | 
					
						
							|  |  |  | 	  || (delete_offset > (history_base + history_length))) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 	  sh_erange (delete_arg, _("history position")); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 	  return (EXECUTION_FAILURE); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       opt = delete_offset; | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |       result = bash_delete_histent (opt - history_base); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |       /* Since remove_history changes history_length, this can happen if | 
					
						
							|  |  |  | 	 we delete the last history entry. */ | 
					
						
							|  |  |  |       if (where_history () > history_length) | 
					
						
							|  |  |  | 	history_set_pos (history_length); | 
					
						
							|  |  |  |       return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |       result = display_history (list); | 
					
						
							|  |  |  |       return (sh_chkwrite (result)); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   filename = list ? list->word->word : get_string_value ("HISTFILE"); | 
					
						
							|  |  |  |   result = EXECUTION_SUCCESS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (flags & AFLAG)		/* Append session's history to file. */ | 
					
						
							|  |  |  |     result = maybe_append_history (filename); | 
					
						
							|  |  |  |   else if (flags & WFLAG)	/* Write entire history. */ | 
					
						
							|  |  |  |     result = write_history (filename); | 
					
						
							|  |  |  |   else if (flags & RFLAG)	/* Read entire file. */ | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |       result = read_history (filename); | 
					
						
							|  |  |  |       history_lines_in_file = history_lines_read_from_file; | 
					
						
							|  |  |  |       /* history_lines_in_file = where_history () + history_base - 1; */ | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   else if (flags & NFLAG)	/* Read `new' history from file. */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       /* Read all of the lines in the file that we haven't already read. */ | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |       old_history_lines = history_lines_in_file; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       obase = history_base; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       using_history (); | 
					
						
							|  |  |  |       result = read_history_range (filename, history_lines_in_file, -1); | 
					
						
							|  |  |  |       using_history (); | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  |       history_lines_in_file = history_lines_read_from_file; | 
					
						
							|  |  |  |       /* history_lines_in_file = where_history () + history_base - 1; */ | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* If we're rewriting the history file at shell exit rather than just | 
					
						
							|  |  |  | 	 appending the lines from this session to it, the question is whether | 
					
						
							|  |  |  | 	 we reset history_lines_this_session to 0, losing any history entries | 
					
						
							|  |  |  | 	 we had before we read the new entries from the history file, or | 
					
						
							|  |  |  | 	 whether we count the new entries we just read from the file as | 
					
						
							|  |  |  | 	 history lines added during this session. | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 	 Right now, we do the latter.  This will cause these history entries | 
					
						
							|  |  |  | 	 to be written to the history file along with any intermediate entries | 
					
						
							|  |  |  | 	 we add when we do a `history -a', but the alternative is losing | 
					
						
							|  |  |  | 	 them altogether. */ | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  |       if (force_append_history == 0) | 
					
						
							|  |  |  | 	history_lines_this_session += history_lines_in_file - old_history_lines + | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 				    history_base - obase; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Accessors for HIST_ENTRY lists that are called HLIST. */ | 
					
						
							|  |  |  | #define histline(i) (hlist[(i)]->line) | 
					
						
							|  |  |  | #define histdata(i) (hlist[(i)]->data) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | static char * | 
					
						
							|  |  |  | histtime (hlist, histtimefmt) | 
					
						
							|  |  |  |      HIST_ENTRY *hlist; | 
					
						
							|  |  |  |      const char *histtimefmt; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static char timestr[128]; | 
					
						
							|  |  |  |   time_t t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   t = history_get_time (hlist); | 
					
						
							|  |  |  |   if (t) | 
					
						
							|  |  |  |     strftime (timestr, sizeof (timestr), histtimefmt, localtime (&t)); | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  |   else if (hlist->timestamp && hlist->timestamp[0]) | 
					
						
							|  |  |  |     snprintf (timestr, sizeof (timestr), _("%s: invalid timestamp"), | 
					
						
							|  |  |  | 	(hlist->timestamp[0] == '#') ? hlist->timestamp + 1: hlist->timestamp); | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   else | 
					
						
							|  |  |  |     strcpy (timestr, "??"); | 
					
						
							|  |  |  |   return timestr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | display_history (list) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   intmax_t limit; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   HIST_ENTRY **hlist; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   char *histtimefmt, *timestr; | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   if (list) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |       if (get_numeric_arg (list, 0, &limit) == 0) | 
					
						
							|  |  |  | 	return (EXECUTION_FAILURE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       if (limit < 0) | 
					
						
							|  |  |  | 	limit = -limit; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |     limit = -1; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   hlist = history_list (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (hlist) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       for (i = 0;  hlist[i]; i++) | 
					
						
							|  |  |  | 	; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |       if (0 <= limit && limit < i) | 
					
						
							|  |  |  | 	i -= limit; | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |       histtimefmt = get_string_value ("HISTTIMEFORMAT"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |       while (hlist[i]) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  QUIT; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  timestr = (histtimefmt && *histtimefmt) ? histtime (hlist[i], histtimefmt) : (char *)NULL; | 
					
						
							|  |  |  | 	  printf ("%5d%c %s%s\n", i + history_base, | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 		  histdata(i) ? '*' : ' ', | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 		  ((timestr && *timestr) ? timestr : ""), | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 		  histline(i)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 	  i++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   return (EXECUTION_SUCCESS); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Remove the last entry in the history list and add each argument in | 
					
						
							|  |  |  |    LIST to the history. */ | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | push_history (list) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   /* Delete the last history entry if it was a single entry added to the | 
					
						
							|  |  |  |      history list (generally the `history -s' itself), or if `history -s' | 
					
						
							|  |  |  |      is being used in a compound command and the compound command was | 
					
						
							|  |  |  |      added to the history as a single element (command-oriented history). | 
					
						
							|  |  |  |      If you don't want history -s to remove the compound command from the | 
					
						
							|  |  |  |      history, change #if 0 to #if 1 below. */ | 
					
						
							|  |  |  | #if 0 | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   if (remember_on_history && hist_last_line_pushed == 0 && | 
					
						
							|  |  |  | 	hist_last_line_added && bash_delete_last_history () == 0) | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | #else | 
					
						
							| 
									
										
										
										
											2014-02-26 09:36:43 -05:00
										 |  |  |   if (remember_on_history && hist_last_line_pushed == 0 && | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | 	(hist_last_line_added || | 
					
						
							|  |  |  | 	  (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history)) | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |       && bash_delete_last_history () == 0) | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   s = string_list (list); | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   /* Call check_add_history with FORCE set to 1 to skip the check against | 
					
						
							|  |  |  |      current_command_line_count.  If history -s is used in a compound | 
					
						
							|  |  |  |      command, the above code will delete the compound command's history | 
					
						
							|  |  |  |      entry and this call will add the line to the history as a separate | 
					
						
							|  |  |  |      entry.  Without FORCE=1, if current_command_line_count were > 1, the | 
					
						
							|  |  |  |      line would be appended to the entry before the just-deleted entry. */ | 
					
						
							|  |  |  |   check_add_history (s, 1);	/* obeys HISTCONTROL, HISTIGNORE */ | 
					
						
							| 
									
										
										
										
											2005-12-07 14:08:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   hist_last_line_pushed = 1;	/* XXX */ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |   free (s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (BANG_HISTORY) | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | expand_and_print_history (list) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *s; | 
					
						
							|  |  |  |   int r, result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |   if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0) | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |     return EXECUTION_FAILURE; | 
					
						
							|  |  |  |   result = EXECUTION_SUCCESS; | 
					
						
							|  |  |  |   while (list) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       r = history_expand (list->word->word, &s); | 
					
						
							|  |  |  |       if (r < 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 	  builtin_error (_("%s: history expansion failed"), list->word->word); | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	  result = EXECUTION_FAILURE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       else | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | 	  fputs (s, stdout); | 
					
						
							|  |  |  | 	  putchar ('\n'); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  |       FREE (s); | 
					
						
							|  |  |  |       list = list->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   fflush (stdout); | 
					
						
							|  |  |  |   return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* BANG_HISTORY */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #endif /* HISTORY */ |