4 //config: This option recreates the prompt string from the environment
5 //config: variable each time it is displayed.
7 +//config:config ASH_HIST_BUFFER
8 +//config: bool "History buffer"
10 +//config: depends on ASH && FEATURE_EDITING_SAVEHISTORY
12 +//config: Allows you to set a temporary location for .ash_history.
13 +//config: History is saved to this custom location, and written out to
14 +//config: its default location (~/.ash_history) upon shell exit.
15 +//config: Useful to prevent wear on flash-based storage devices.
17 +//config:config ASH_HIST_BUFFER_PATH
18 +//config: string "History buffer location"
19 +//config: default "/tmp"
20 +//config: depends on ASH && ASH_HIST_BUFFER
22 +//config: Directory which will be used to save the shell history until
23 +//config: ash is exited.
26 //usage:#define ash_trivial_usage NOUSAGE_STR
27 //usage:#define ash_full_usage ""
28 @@ -12810,6 +12828,14 @@ exitshell(void)
32 +#if ENABLE_ASH_HIST_BUFFER
33 + const char *tmphistory = lookupvar("HISTFILE");
34 + const char *storedhistory = lookupvar("STOREDHISTFILE");
36 + if (storedhistory) /* is NULL when setting up the history buffer failed; check this before copying */
37 + copy_file(tmphistory, storedhistory, FILEUTILS_FORCE | FILEUTILS_DEREFERENCE | FILEUTILS_PRESERVE_STATUS);
41 TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
42 if (setjmp(loc.loc)) {
43 @@ -13056,9 +13082,61 @@ int ash_main(int argc UNUSED_PARAM, char
45 hp = lookupvar("HOME");
47 +#if ENABLE_ASH_HIST_BUFFER
50 + char *storedhistory;
51 + const char *user = lookupvar("USER");
53 + tmppath = concat_path_file(CONFIG_ASH_HIST_BUFFER_PATH, user);
54 + tmphistory = concat_path_file(tmppath, ".ash_history");
55 + storedhistory = concat_path_file(hp, ".ash_history");
57 + if (access(tmphistory, R_OK | W_OK) == -1) {
58 + if (access(CONFIG_ASH_HIST_BUFFER_PATH, R_OK == -1)) {
59 + bb_simple_perror_msg("could not access history buffer path");
62 + if (bb_make_directory(tmppath, 0700, FILEUTILS_RECUR)) {
63 + /* bb_make_directory is noisy, no need for an additional error message here */
66 + if (access(storedhistory, R_OK) == -1) {
67 + creat(tmphistory, 0644);
69 + copy_file(storedhistory, tmphistory, FILEUTILS_FORCE | FILEUTILS_DEREFERENCE | FILEUTILS_PRESERVE_STATUS);
71 + } else { /* (security) checks before reusing existing temporary history file */
72 + struct stat stat_tmphistory;
73 + lstat(tmphistory, &stat_tmphistory);
74 + if (!S_ISREG(stat_tmphistory.st_mode)) {
76 + bb_simple_perror_msg("history buffer is not a regular file");
79 + if (stat_tmphistory.st_uid != geteuid() || stat_tmphistory.st_gid != getegid()) {
81 + bb_simple_perror_msg("history buffer is not exclusive to the shell user");
85 + setvar("STOREDHISTFILE", storedhistory, 0);
90 + bb_simple_perror_msg("shell history will not be saved");
91 + tmphistory = xasprintf("/dev/null");
93 + setvar("HISTFILE", tmphistory, 0);
94 + free(storedhistory);
98 char *defhp = concat_path_file(hp, ".ash_history");
99 setvar("HISTFILE", defhp, 0);