diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-22 07:21:38 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-22 07:21:38 +0000 |
commit | 8e1c71529c2bf38a04d4a117e625e59044a0785a (patch) | |
tree | 2f115293c25e7ee9307f268ec198e2cf486ff070 | |
parent | 00cdbd8fc20a4e2e2208f90a2691a3806c931b06 (diff) | |
download | busybox-w32-8e1c71529c2bf38a04d4a117e625e59044a0785a.tar.gz busybox-w32-8e1c71529c2bf38a04d4a117e625e59044a0785a.tar.bz2 busybox-w32-8e1c71529c2bf38a04d4a117e625e59044a0785a.zip |
Convert cmdedit into more generic line input facility
(make history and completion optional at runtime).
Use it for fdisk, as an example.
Some unrelated fixes in fdisk are also here.
-rw-r--r-- | include/libbb.h | 36 | ||||
-rw-r--r-- | shell/Kbuild | 10 | ||||
-rw-r--r-- | shell/ash.c | 106 | ||||
-rw-r--r-- | shell/cmdedit.c | 316 | ||||
-rw-r--r-- | shell/cmdedit.h | 21 | ||||
-rw-r--r-- | shell/hush.c | 13 | ||||
-rw-r--r-- | shell/lash.c | 14 | ||||
-rw-r--r-- | shell/msh.c | 26 | ||||
-rw-r--r-- | util-linux/fdisk.c | 309 | ||||
-rw-r--r-- | util-linux/fdisk_osf.c | 46 |
10 files changed, 459 insertions, 438 deletions
diff --git a/include/libbb.h b/include/libbb.h index 0b066d1bd..f990b0ebd 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -583,6 +583,42 @@ extern unsigned long long bb_makedev(unsigned int major, unsigned int minor); | |||
583 | #endif | 583 | #endif |
584 | 584 | ||
585 | 585 | ||
586 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
587 | /* It's NOT just ENABLEd or disabled. It's a number: */ | ||
588 | #ifdef CONFIG_FEATURE_COMMAND_HISTORY | ||
589 | #define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0) | ||
590 | #else | ||
591 | #define MAX_HISTORY 0 | ||
592 | #endif | ||
593 | struct line_input_t { | ||
594 | int flags; | ||
595 | const char *path_lookup; | ||
596 | #if MAX_HISTORY | ||
597 | int cnt_history; | ||
598 | int cur_history; | ||
599 | USE_FEATURE_COMMAND_SAVEHISTORY(const char *hist_file;) | ||
600 | char *history[MAX_HISTORY + 1]; | ||
601 | #endif | ||
602 | }; | ||
603 | enum { | ||
604 | DO_HISTORY = 1 * (MAX_HISTORY > 0), | ||
605 | SAVE_HISTORY = 2 * (MAX_HISTORY > 0) * ENABLE_FEATURE_COMMAND_SAVEHISTORY, | ||
606 | TAB_COMPLETION = 4 * ENABLE_FEATURE_COMMAND_TAB_COMPLETION, | ||
607 | USERNAME_COMPLETION = 8 * ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION, | ||
608 | VI_MODE = 0x10 * ENABLE_FEATURE_COMMAND_EDITING_VI, | ||
609 | WITH_PATH_LOOKUP = 0x20, | ||
610 | FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION, | ||
611 | }; | ||
612 | typedef struct line_input_t line_input_t; | ||
613 | line_input_t *new_line_input_t(int flags); | ||
614 | int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state); | ||
615 | #else | ||
616 | int read_line_input(const char* prompt, char* command, int maxsize); | ||
617 | #define read_line_input(prompt, command, maxsize, state) \ | ||
618 | read_line_input(prompt, command, maxsize) | ||
619 | #endif | ||
620 | |||
621 | |||
586 | #ifndef COMM_LEN | 622 | #ifndef COMM_LEN |
587 | #ifdef TASK_COMM_LEN | 623 | #ifdef TASK_COMM_LEN |
588 | enum { COMM_LEN = TASK_COMM_LEN }; | 624 | enum { COMM_LEN = TASK_COMM_LEN }; |
diff --git a/shell/Kbuild b/shell/Kbuild index eb0199ee2..9c60698f7 100644 --- a/shell/Kbuild +++ b/shell/Kbuild | |||
@@ -5,8 +5,8 @@ | |||
5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. | 5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. |
6 | 6 | ||
7 | lib-y:= | 7 | lib-y:= |
8 | lib-$(CONFIG_ASH) += ash.o | 8 | lib-y += cmdedit.o |
9 | lib-$(CONFIG_HUSH) += hush.o | 9 | lib-$(CONFIG_ASH) += ash.o |
10 | lib-$(CONFIG_LASH) += lash.o | 10 | lib-$(CONFIG_HUSH) += hush.o |
11 | lib-$(CONFIG_MSH) += msh.o | 11 | lib-$(CONFIG_LASH) += lash.o |
12 | lib-$(CONFIG_FEATURE_COMMAND_EDITING) += cmdedit.o | 12 | lib-$(CONFIG_MSH) += msh.o |
diff --git a/shell/ash.c b/shell/ash.c index 2db3302c7..8afdf3d21 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -92,7 +92,6 @@ | |||
92 | #include <termios.h> | 92 | #include <termios.h> |
93 | #endif | 93 | #endif |
94 | 94 | ||
95 | #include "cmdedit.h" | ||
96 | 95 | ||
97 | #ifdef __GLIBC__ | 96 | #ifdef __GLIBC__ |
98 | /* glibc sucks */ | 97 | /* glibc sucks */ |
@@ -1238,7 +1237,7 @@ static int fgcmd(int, char **); | |||
1238 | static int getoptscmd(int, char **); | 1237 | static int getoptscmd(int, char **); |
1239 | #endif | 1238 | #endif |
1240 | static int hashcmd(int, char **); | 1239 | static int hashcmd(int, char **); |
1241 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 1240 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
1242 | static int helpcmd(int argc, char **argv); | 1241 | static int helpcmd(int argc, char **argv); |
1243 | #endif | 1242 | #endif |
1244 | #if JOBS | 1243 | #if JOBS |
@@ -1347,7 +1346,7 @@ static const struct builtincmd builtincmd[] = { | |||
1347 | { BUILTIN_REGULAR "getopts", getoptscmd }, | 1346 | { BUILTIN_REGULAR "getopts", getoptscmd }, |
1348 | #endif | 1347 | #endif |
1349 | { BUILTIN_NOSPEC "hash", hashcmd }, | 1348 | { BUILTIN_NOSPEC "hash", hashcmd }, |
1350 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 1349 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
1351 | { BUILTIN_NOSPEC "help", helpcmd }, | 1350 | { BUILTIN_NOSPEC "help", helpcmd }, |
1352 | #endif | 1351 | #endif |
1353 | #if JOBS | 1352 | #if JOBS |
@@ -1529,7 +1528,7 @@ static struct var varinit[] = { | |||
1529 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all }, | 1528 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all }, |
1530 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype }, | 1529 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype }, |
1531 | #endif | 1530 | #endif |
1532 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 1531 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
1533 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL }, | 1532 | {0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL }, |
1534 | #endif | 1533 | #endif |
1535 | }; | 1534 | }; |
@@ -1934,10 +1933,6 @@ struct shparam { | |||
1934 | #define debug optlist[15] | 1933 | #define debug optlist[15] |
1935 | #endif | 1934 | #endif |
1936 | 1935 | ||
1937 | #ifndef CONFIG_FEATURE_COMMAND_EDITING_VI | ||
1938 | #define setvimode(on) viflag = 0 /* forcibly keep the option off */ | ||
1939 | #endif | ||
1940 | |||
1941 | /* options.c */ | 1936 | /* options.c */ |
1942 | 1937 | ||
1943 | 1938 | ||
@@ -3718,7 +3713,7 @@ shellexec(char **argv, const char *path, int idx) | |||
3718 | clearredir(1); | 3713 | clearredir(1); |
3719 | envp = environment(); | 3714 | envp = environment(); |
3720 | if (strchr(argv[0], '/') || is_safe_applet(argv[0]) | 3715 | if (strchr(argv[0], '/') || is_safe_applet(argv[0]) |
3721 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3716 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3722 | || find_applet_by_name(argv[0]) | 3717 | || find_applet_by_name(argv[0]) |
3723 | #endif | 3718 | #endif |
3724 | ) { | 3719 | ) { |
@@ -3775,7 +3770,7 @@ tryexec(char *cmd, char **argv, char **envp) | |||
3775 | applet_name = cmd; | 3770 | applet_name = cmd; |
3776 | exit(a->main(argc, argv)); | 3771 | exit(a->main(argc, argv)); |
3777 | } | 3772 | } |
3778 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3773 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3779 | if (find_applet_by_name(cmd) != NULL) { | 3774 | if (find_applet_by_name(cmd) != NULL) { |
3780 | /* re-exec ourselves with the new arguments */ | 3775 | /* re-exec ourselves with the new arguments */ |
3781 | execve(CONFIG_BUSYBOX_EXEC_PATH,argv,envp); | 3776 | execve(CONFIG_BUSYBOX_EXEC_PATH,argv,envp); |
@@ -3949,7 +3944,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path) | |||
3949 | return; | 3944 | return; |
3950 | } | 3945 | } |
3951 | 3946 | ||
3952 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 3947 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
3953 | if (find_applet_by_name(name)) { | 3948 | if (find_applet_by_name(name)) { |
3954 | entry->cmdtype = CMDNORMAL; | 3949 | entry->cmdtype = CMDNORMAL; |
3955 | entry->u.index = -1; | 3950 | entry->u.index = -1; |
@@ -6045,21 +6040,18 @@ static char * pfgets(char *line, int len) | |||
6045 | } | 6040 | } |
6046 | 6041 | ||
6047 | 6042 | ||
6048 | 6043 | #if ENABLE_FEATURE_COMMAND_EDITING | |
6049 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 6044 | static line_input_t *line_input_state; |
6050 | #ifdef CONFIG_ASH_EXPAND_PRMT | 6045 | //static SKIP_ASH_EXPAND_PRMT(const) char *cmdedit_prompt; |
6051 | static char *cmdedit_prompt; | ||
6052 | #else | ||
6053 | static const char *cmdedit_prompt; | 6046 | static const char *cmdedit_prompt; |
6054 | #endif | ||
6055 | static void putprompt(const char *s) | 6047 | static void putprompt(const char *s) |
6056 | { | 6048 | { |
6057 | #ifdef CONFIG_ASH_EXPAND_PRMT | 6049 | if (ENABLE_ASH_EXPAND_PRMT) { |
6058 | free(cmdedit_prompt); | 6050 | free((char*)cmdedit_prompt); |
6059 | cmdedit_prompt = xstrdup(s); | 6051 | cmdedit_prompt = xstrdup(s); |
6060 | #else | 6052 | return; |
6053 | } | ||
6061 | cmdedit_prompt = s; | 6054 | cmdedit_prompt = s; |
6062 | #endif | ||
6063 | } | 6055 | } |
6064 | #else | 6056 | #else |
6065 | static void putprompt(const char *s) | 6057 | static void putprompt(const char *s) |
@@ -6068,6 +6060,16 @@ static void putprompt(const char *s) | |||
6068 | } | 6060 | } |
6069 | #endif | 6061 | #endif |
6070 | 6062 | ||
6063 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | ||
6064 | #define setvimode(on) do { \ | ||
6065 | if (on) line_input_state->flags |= VI_MODE; \ | ||
6066 | else line_input_state->flags &= ~VI_MODE; \ | ||
6067 | } while (0) | ||
6068 | #else | ||
6069 | #define setvimode(on) viflag = 0 /* forcibly keep the option off */ | ||
6070 | #endif | ||
6071 | |||
6072 | |||
6071 | static int preadfd(void) | 6073 | static int preadfd(void) |
6072 | { | 6074 | { |
6073 | int nr; | 6075 | int nr; |
@@ -6075,25 +6077,25 @@ static int preadfd(void) | |||
6075 | parsenextc = buf; | 6077 | parsenextc = buf; |
6076 | 6078 | ||
6077 | retry: | 6079 | retry: |
6078 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 6080 | #if ENABLE_FEATURE_COMMAND_EDITING |
6079 | if (!iflag || parsefile->fd) | 6081 | if (!iflag || parsefile->fd) |
6080 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); | 6082 | nr = safe_read(parsefile->fd, buf, BUFSIZ - 1); |
6081 | else { | 6083 | else { |
6082 | #ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION | 6084 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
6083 | cmdedit_path_lookup = pathval(); | 6085 | line_input_state->path_lookup = pathval(); |
6084 | #endif | 6086 | #endif |
6085 | nr = cmdedit_read_input((char *) cmdedit_prompt, buf); | 6087 | nr = read_line_input(cmdedit_prompt, buf, BUFSIZ, line_input_state); |
6086 | if(nr == 0) { | 6088 | if (nr == 0) { |
6087 | /* Ctrl+C presend */ | 6089 | /* Ctrl+C pressed */ |
6088 | if(trap[SIGINT]) { | 6090 | if (trap[SIGINT]) { |
6089 | buf[0] = '\n'; | 6091 | buf[0] = '\n'; |
6090 | buf[1] = 0; | 6092 | buf[1] = '\0'; |
6091 | raise(SIGINT); | 6093 | raise(SIGINT); |
6092 | return 1; | 6094 | return 1; |
6093 | } | 6095 | } |
6094 | goto retry; | 6096 | goto retry; |
6095 | } | 6097 | } |
6096 | if(nr < 0 && errno == 0) { | 6098 | if (nr < 0 && errno == 0) { |
6097 | /* Ctrl+D presend */ | 6099 | /* Ctrl+D presend */ |
6098 | nr = 0; | 6100 | nr = 0; |
6099 | } | 6101 | } |
@@ -7913,6 +7915,10 @@ ash_main(int argc, char **argv) | |||
7913 | #if PROFILE | 7915 | #if PROFILE |
7914 | monitor(4, etext, profile_buf, sizeof profile_buf, 50); | 7916 | monitor(4, etext, profile_buf, sizeof profile_buf, 50); |
7915 | #endif | 7917 | #endif |
7918 | |||
7919 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
7920 | line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); | ||
7921 | #endif | ||
7916 | state = 0; | 7922 | state = 0; |
7917 | if (setjmp(jmploc.loc)) { | 7923 | if (setjmp(jmploc.loc)) { |
7918 | int e; | 7924 | int e; |
@@ -7954,11 +7960,11 @@ ash_main(int argc, char **argv) | |||
7954 | init(); | 7960 | init(); |
7955 | setstackmark(&smark); | 7961 | setstackmark(&smark); |
7956 | procargs(argc, argv); | 7962 | procargs(argc, argv); |
7957 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 7963 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
7958 | if ( iflag ) { | 7964 | if (iflag) { |
7959 | const char *hp = lookupvar("HISTFILE"); | 7965 | const char *hp = lookupvar("HISTFILE"); |
7960 | 7966 | ||
7961 | if(hp == NULL ) { | 7967 | if (hp == NULL) { |
7962 | hp = lookupvar("HOME"); | 7968 | hp = lookupvar("HOME"); |
7963 | if(hp != NULL) { | 7969 | if(hp != NULL) { |
7964 | char *defhp = concat_path_file(hp, ".ash_history"); | 7970 | char *defhp = concat_path_file(hp, ".ash_history"); |
@@ -7995,15 +8001,15 @@ state3: | |||
7995 | evalstring(minusc, 0); | 8001 | evalstring(minusc, 0); |
7996 | 8002 | ||
7997 | if (sflag || minusc == NULL) { | 8003 | if (sflag || minusc == NULL) { |
7998 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | 8004 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
7999 | if ( iflag ) { | 8005 | if ( iflag ) { |
8000 | const char *hp = lookupvar("HISTFILE"); | 8006 | const char *hp = lookupvar("HISTFILE"); |
8001 | 8007 | ||
8002 | if(hp != NULL ) | 8008 | if (hp != NULL) |
8003 | load_history ( hp ); | 8009 | line_input_state->hist_file = hp; |
8004 | } | 8010 | } |
8005 | #endif | 8011 | #endif |
8006 | state4: /* XXX ??? - why isn't this before the "if" statement */ | 8012 | state4: /* XXX ??? - why isn't this before the "if" statement */ |
8007 | cmdloop(1); | 8013 | cmdloop(1); |
8008 | } | 8014 | } |
8009 | #if PROFILE | 8015 | #if PROFILE |
@@ -11880,7 +11886,7 @@ setinteractive(int on) | |||
11880 | setsignal(SIGINT); | 11886 | setsignal(SIGINT); |
11881 | setsignal(SIGQUIT); | 11887 | setsignal(SIGQUIT); |
11882 | setsignal(SIGTERM); | 11888 | setsignal(SIGTERM); |
11883 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 11889 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
11884 | if(is_interactive > 1) { | 11890 | if(is_interactive > 1) { |
11885 | /* Looks like they want an interactive shell */ | 11891 | /* Looks like they want an interactive shell */ |
11886 | static int do_banner; | 11892 | static int do_banner; |
@@ -11897,7 +11903,7 @@ setinteractive(int on) | |||
11897 | } | 11903 | } |
11898 | 11904 | ||
11899 | 11905 | ||
11900 | #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET | 11906 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
11901 | /*** List the available builtins ***/ | 11907 | /*** List the available builtins ***/ |
11902 | 11908 | ||
11903 | static int helpcmd(int argc, char **argv) | 11909 | static int helpcmd(int argc, char **argv) |
@@ -11913,7 +11919,7 @@ static int helpcmd(int argc, char **argv) | |||
11913 | col = 0; | 11919 | col = 0; |
11914 | } | 11920 | } |
11915 | } | 11921 | } |
11916 | #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL | 11922 | #if ENABLE_FEATURE_SH_STANDALONE_SHELL |
11917 | for (i = 0; i < NUM_APPLETS; i++) { | 11923 | for (i = 0; i < NUM_APPLETS; i++) { |
11918 | col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name); | 11924 | col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name); |
11919 | if (col > 60) { | 11925 | if (col > 60) { |
@@ -11945,7 +11951,7 @@ exitshell(void) | |||
11945 | /* dash bug: it just does _exit(exitstatus) here | 11951 | /* dash bug: it just does _exit(exitstatus) here |
11946 | * but we have to do setjobctl(0) first! | 11952 | * but we have to do setjobctl(0) first! |
11947 | * (bug is still not fixed in dash-0.5.3 - if you run dash | 11953 | * (bug is still not fixed in dash-0.5.3 - if you run dash |
11948 | * under Midnight Commander, on exit MC is backgrounded) */ | 11954 | * under Midnight Commander, on exit from dash MC is backgrounded) */ |
11949 | status = exitstatus; | 11955 | status = exitstatus; |
11950 | goto out; | 11956 | goto out; |
11951 | } | 11957 | } |
@@ -11955,14 +11961,6 @@ exitshell(void) | |||
11955 | evalstring(p, 0); | 11961 | evalstring(p, 0); |
11956 | } | 11962 | } |
11957 | flushall(); | 11963 | flushall(); |
11958 | #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY | ||
11959 | if (iflag && rootshell) { | ||
11960 | const char *hp = lookupvar("HISTFILE"); | ||
11961 | |||
11962 | if (hp != NULL) | ||
11963 | save_history(hp); | ||
11964 | } | ||
11965 | #endif | ||
11966 | out: | 11964 | out: |
11967 | setjobctl(0); | 11965 | setjobctl(0); |
11968 | _exit(status); | 11966 | _exit(status); |
@@ -13491,7 +13489,7 @@ static const char op_tokens[] = { | |||
13491 | #define endexpression &op_tokens[sizeof(op_tokens)-7] | 13489 | #define endexpression &op_tokens[sizeof(op_tokens)-7] |
13492 | 13490 | ||
13493 | 13491 | ||
13494 | static arith_t arith (const char *expr, int *perrcode) | 13492 | static arith_t arith(const char *expr, int *perrcode) |
13495 | { | 13493 | { |
13496 | char arithval; /* Current character under analysis */ | 13494 | char arithval; /* Current character under analysis */ |
13497 | operator lasttok, op; | 13495 | operator lasttok, op; |
diff --git a/shell/cmdedit.c b/shell/cmdedit.c index a1432af15..554a4ebec 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | #include <sys/ioctl.h> | 31 | #include <sys/ioctl.h> |
32 | #include "busybox.h" | 32 | #include "busybox.h" |
33 | #include "cmdedit.h" | ||
34 | 33 | ||
35 | 34 | ||
36 | /* FIXME: obsolete CONFIG item? */ | 35 | /* FIXME: obsolete CONFIG item? */ |
@@ -51,7 +50,6 @@ | |||
51 | /* Entire file (except TESTing part) sits inside this #if */ | 50 | /* Entire file (except TESTing part) sits inside this #if */ |
52 | #if ENABLE_FEATURE_COMMAND_EDITING | 51 | #if ENABLE_FEATURE_COMMAND_EDITING |
53 | 52 | ||
54 | |||
55 | #if ENABLE_LOCALE_SUPPORT | 53 | #if ENABLE_LOCALE_SUPPORT |
56 | #define Isprint(c) isprint(c) | 54 | #define Isprint(c) isprint(c) |
57 | #else | 55 | #else |
@@ -61,29 +59,21 @@ | |||
61 | #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ | 59 | #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ |
62 | (ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION || ENABLE_FEATURE_SH_FANCY_PROMPT) | 60 | (ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION || ENABLE_FEATURE_SH_FANCY_PROMPT) |
63 | 61 | ||
64 | /* Maximum length of command line history */ | ||
65 | #if !ENABLE_FEATURE_COMMAND_HISTORY | ||
66 | #define MAX_HISTORY 15 | ||
67 | #else | ||
68 | #define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0) | ||
69 | #endif | ||
70 | 62 | ||
63 | static line_input_t *state; | ||
71 | 64 | ||
72 | /* Current termios and the previous termios before starting sh */ | ||
73 | static struct termios initial_settings, new_settings; | 65 | static struct termios initial_settings, new_settings; |
74 | 66 | ||
75 | static | 67 | static volatile unsigned cmdedit_termw = 80; /* actual terminal width */ |
76 | volatile unsigned cmdedit_termw = 80; /* actual terminal width */ | ||
77 | |||
78 | 68 | ||
79 | static int cmdedit_x; /* real x terminal position */ | 69 | static int cmdedit_x; /* real x terminal position */ |
80 | static int cmdedit_y; /* pseudoreal y terminal position */ | 70 | static int cmdedit_y; /* pseudoreal y terminal position */ |
81 | static int cmdedit_prmt_len; /* length of prompt (without colors etc) */ | 71 | static int cmdedit_prmt_len; /* length of prompt (without colors etc) */ |
82 | 72 | ||
83 | static int cursor; | 73 | static unsigned cursor; |
84 | static int len; | 74 | static unsigned command_len; |
85 | static char *command_ps; | 75 | static char *command_ps; |
86 | static SKIP_FEATURE_SH_FANCY_PROMPT(const) char *cmdedit_prompt; | 76 | static const char *cmdedit_prompt; |
87 | 77 | ||
88 | #if ENABLE_FEATURE_SH_FANCY_PROMPT | 78 | #if ENABLE_FEATURE_SH_FANCY_PROMPT |
89 | static char *hostname_buf; | 79 | static char *hostname_buf; |
@@ -142,7 +132,7 @@ static void cmdedit_set_out_char(int next_char) | |||
142 | /* Move to end of line (by printing all chars till the end) */ | 132 | /* Move to end of line (by printing all chars till the end) */ |
143 | static void input_end(void) | 133 | static void input_end(void) |
144 | { | 134 | { |
145 | while (cursor < len) | 135 | while (cursor < command_len) |
146 | cmdedit_set_out_char(' '); | 136 | cmdedit_set_out_char(' '); |
147 | } | 137 | } |
148 | 138 | ||
@@ -200,7 +190,7 @@ static void input_backward(unsigned num) | |||
200 | static void put_prompt(void) | 190 | static void put_prompt(void) |
201 | { | 191 | { |
202 | out1str(cmdedit_prompt); | 192 | out1str(cmdedit_prompt); |
203 | cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */ | 193 | cmdedit_x = cmdedit_prmt_len; |
204 | cursor = 0; | 194 | cursor = 0; |
205 | // Huh? what if cmdedit_prmt_len >= width? | 195 | // Huh? what if cmdedit_prmt_len >= width? |
206 | cmdedit_y = 0; /* new quasireal y */ | 196 | cmdedit_y = 0; /* new quasireal y */ |
@@ -231,7 +221,7 @@ static void input_delete(int save) | |||
231 | { | 221 | { |
232 | int j = cursor; | 222 | int j = cursor; |
233 | 223 | ||
234 | if (j == len) | 224 | if (j == command_len) |
235 | return; | 225 | return; |
236 | 226 | ||
237 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | 227 | #if ENABLE_FEATURE_COMMAND_EDITING_VI |
@@ -249,7 +239,7 @@ static void input_delete(int save) | |||
249 | #endif | 239 | #endif |
250 | 240 | ||
251 | strcpy(command_ps + j, command_ps + j + 1); | 241 | strcpy(command_ps + j, command_ps + j + 1); |
252 | len--; | 242 | command_len--; |
253 | input_end(); /* rewrite new line */ | 243 | input_end(); /* rewrite new line */ |
254 | cmdedit_set_out_char(' '); /* erase char */ | 244 | cmdedit_set_out_char(' '); /* erase char */ |
255 | input_backward(cursor - j); /* back to old pos cursor */ | 245 | input_backward(cursor - j); /* back to old pos cursor */ |
@@ -285,7 +275,7 @@ static void input_backspace(void) | |||
285 | /* Move forward one character */ | 275 | /* Move forward one character */ |
286 | static void input_forward(void) | 276 | static void input_forward(void) |
287 | { | 277 | { |
288 | if (cursor < len) | 278 | if (cursor < command_len) |
289 | cmdedit_set_out_char(command_ps[cursor + 1]); | 279 | cmdedit_set_out_char(command_ps[cursor + 1]); |
290 | } | 280 | } |
291 | 281 | ||
@@ -372,54 +362,50 @@ enum { | |||
372 | FIND_FILE_ONLY = 2, | 362 | FIND_FILE_ONLY = 2, |
373 | }; | 363 | }; |
374 | 364 | ||
375 | #if ENABLE_ASH | ||
376 | const char *cmdedit_path_lookup; | ||
377 | #endif | ||
378 | static int path_parse(char ***p, int flags) | 365 | static int path_parse(char ***p, int flags) |
379 | { | 366 | { |
380 | int npth; | 367 | int npth; |
381 | const char *tmp; | 368 | const char *tmp; |
382 | #if ENABLE_ASH | 369 | const char *pth; |
383 | const char *pth = cmdedit_path_lookup; | 370 | char **res; |
384 | #else | ||
385 | const char *pth = getenv("PATH") | ||
386 | #endif | ||
387 | 371 | ||
388 | /* if not setenv PATH variable, to search cur dir "." */ | 372 | /* if not setenv PATH variable, to search cur dir "." */ |
389 | if (flags != FIND_EXE_ONLY) | 373 | if (flags != FIND_EXE_ONLY) |
390 | return 1; | 374 | return 1; |
375 | |||
376 | if (state->flags & WITH_PATH_LOOKUP) | ||
377 | pth = state->path_lookup; | ||
378 | else | ||
379 | pth = getenv("PATH"); | ||
391 | /* PATH=<empty> or PATH=:<empty> */ | 380 | /* PATH=<empty> or PATH=:<empty> */ |
392 | if (!pth || !pth[0] || LONE_CHAR(pth, ':')) | 381 | if (!pth || !pth[0] || LONE_CHAR(pth, ':')) |
393 | return 1; | 382 | return 1; |
394 | 383 | ||
395 | tmp = pth; | 384 | tmp = pth; |
396 | npth = 0; | 385 | npth = 1; /* path component count */ |
397 | |||
398 | while (1) { | 386 | while (1) { |
399 | npth++; /* count words is + 1 count ':' */ | ||
400 | tmp = strchr(tmp, ':'); | 387 | tmp = strchr(tmp, ':'); |
401 | if (!tmp) | 388 | if (!tmp) |
402 | break; | 389 | break; |
403 | if (*++tmp == '\0') | 390 | if (*++tmp == '\0') |
404 | break; /* :<empty> */ | 391 | break; /* :<empty> */ |
392 | npth++; | ||
405 | } | 393 | } |
406 | 394 | ||
407 | *p = xmalloc(npth * sizeof(char *)); | 395 | res = xmalloc(npth * sizeof(char*)); |
408 | 396 | res[0] = xstrdup(pth); | |
409 | tmp = pth; | 397 | tmp = pth; |
410 | (*p)[0] = xstrdup(tmp); | 398 | npth = 1; |
411 | npth = 1; /* count words is + 1 count ':' */ | ||
412 | |||
413 | while (1) { | 399 | while (1) { |
414 | tmp = strchr(tmp, ':'); | 400 | tmp = strchr(tmp, ':'); |
415 | if (!tmp) | 401 | if (!tmp) |
416 | break; | 402 | break; |
417 | (*p)[0][(tmp - pth)] = 0; /* ':' -> '\0' */ | 403 | *tmp++ = '\0'; /* ':' -> '\0' */ |
418 | if (*++tmp == 0) | 404 | if (*tmp == '\0') |
419 | break; /* :<empty> */ | 405 | break; /* :<empty> */ |
420 | (*p)[npth++] = &(*p)[0][(tmp - pth)]; /* p[next]=p[0][&'\0'+1] */ | 406 | res[npth++] = tmp; |
421 | } | 407 | } |
422 | 408 | *p = res; | |
423 | return npth; | 409 | return npth; |
424 | } | 410 | } |
425 | 411 | ||
@@ -742,6 +728,9 @@ static int match_compare(const void *a, const void *b) | |||
742 | /* Do TAB completion */ | 728 | /* Do TAB completion */ |
743 | static void input_tab(int *lastWasTab) | 729 | static void input_tab(int *lastWasTab) |
744 | { | 730 | { |
731 | if (!(state->flags & TAB_COMPLETION)) | ||
732 | return; | ||
733 | |||
745 | if (!*lastWasTab) { | 734 | if (!*lastWasTab) { |
746 | char *tmp, *tmp1; | 735 | char *tmp, *tmp1; |
747 | int len_found; | 736 | int len_found; |
@@ -764,13 +753,13 @@ static void input_tab(int *lastWasTab) | |||
764 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION | 753 | #if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION |
765 | /* If the word starts with `~' and there is no slash in the word, | 754 | /* If the word starts with `~' and there is no slash in the word, |
766 | * then try completing this word as a username. */ | 755 | * then try completing this word as a username. */ |
767 | 756 | if (state->flags & USERNAME_COMPLETION) | |
768 | if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0) | 757 | if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0) |
769 | username_tab_completion(matchBuf, NULL); | 758 | username_tab_completion(matchBuf, NULL); |
770 | if (!matches) | ||
771 | #endif | 759 | #endif |
772 | /* Try to match any executable in our path and everything | 760 | /* Try to match any executable in our path and everything |
773 | * in the current working directory */ | 761 | * in the current working directory */ |
762 | if (!matches) | ||
774 | exe_n_cwd_tab_completion(matchBuf, find_type); | 763 | exe_n_cwd_tab_completion(matchBuf, find_type); |
775 | /* Sort, then remove any duplicates found */ | 764 | /* Sort, then remove any duplicates found */ |
776 | if (matches) { | 765 | if (matches) { |
@@ -855,51 +844,48 @@ static void input_tab(int *lastWasTab) | |||
855 | } | 844 | } |
856 | } | 845 | } |
857 | 846 | ||
847 | #else | ||
848 | #define input_tab(a) ((void)0) | ||
858 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ | 849 | #endif /* FEATURE_COMMAND_TAB_COMPLETION */ |
859 | 850 | ||
860 | 851 | ||
861 | #if MAX_HISTORY > 0 | 852 | #if MAX_HISTORY > 0 |
862 | 853 | ||
863 | static char *history[MAX_HISTORY+1]; /* history + current */ | 854 | /* state->flags is already checked to be nonzero */ |
864 | /* saved history lines */ | ||
865 | static int n_history; | ||
866 | /* current pointer to history line */ | ||
867 | static int cur_history; | ||
868 | |||
869 | static void get_previous_history(void) | 855 | static void get_previous_history(void) |
870 | { | 856 | { |
871 | if (command_ps[0] != '\0' || history[cur_history] == NULL) { | 857 | if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) { |
872 | free(history[cur_history]); | 858 | free(state->history[state->cur_history]); |
873 | history[cur_history] = xstrdup(command_ps); | 859 | state->history[state->cur_history] = xstrdup(command_ps); |
874 | } | 860 | } |
875 | cur_history--; | 861 | state->cur_history--; |
876 | } | 862 | } |
877 | 863 | ||
878 | static int get_next_history(void) | 864 | static int get_next_history(void) |
879 | { | 865 | { |
880 | int ch = cur_history; | 866 | if (state->flags & DO_HISTORY) { |
881 | 867 | int ch = state->cur_history; | |
882 | if (ch < n_history) { | 868 | if (ch < state->cnt_history) { |
883 | get_previous_history(); /* save the current history line */ | 869 | get_previous_history(); /* save the current history line */ |
884 | cur_history = ch + 1; | 870 | state->cur_history = ch + 1; |
885 | return cur_history; | 871 | return state->cur_history; |
886 | } else { | 872 | } |
887 | beep(); | ||
888 | return 0; | ||
889 | } | 873 | } |
874 | beep(); | ||
875 | return 0; | ||
890 | } | 876 | } |
891 | 877 | ||
892 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY | 878 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY |
879 | /* state->flags is already checked to be nonzero */ | ||
893 | void load_history(const char *fromfile) | 880 | void load_history(const char *fromfile) |
894 | { | 881 | { |
895 | FILE *fp; | 882 | FILE *fp; |
896 | int hi; | 883 | int hi; |
897 | 884 | ||
898 | /* cleanup old */ | 885 | /* cleanup old */ |
899 | 886 | for (hi = state->cnt_history; hi > 0;) { | |
900 | for (hi = n_history; hi > 0;) { | ||
901 | hi--; | 887 | hi--; |
902 | free(history[hi]); | 888 | free(state->history[hi]); |
903 | } | 889 | } |
904 | 890 | ||
905 | fp = fopen(fromfile, "r"); | 891 | fp = fopen(fromfile, "r"); |
@@ -917,29 +903,62 @@ void load_history(const char *fromfile) | |||
917 | free(hl); | 903 | free(hl); |
918 | continue; | 904 | continue; |
919 | } | 905 | } |
920 | history[hi++] = hl; | 906 | state->history[hi++] = hl; |
921 | } | 907 | } |
922 | fclose(fp); | 908 | fclose(fp); |
923 | } | 909 | } |
924 | cur_history = n_history = hi; | 910 | state->cur_history = state->cnt_history = hi; |
925 | } | 911 | } |
926 | 912 | ||
913 | /* state->flags is already checked to be nonzero */ | ||
927 | void save_history(const char *tofile) | 914 | void save_history(const char *tofile) |
928 | { | 915 | { |
929 | FILE *fp = fopen(tofile, "w"); | 916 | FILE *fp; |
930 | 917 | ||
918 | fp = fopen(tofile, "w"); | ||
931 | if (fp) { | 919 | if (fp) { |
932 | int i; | 920 | int i; |
933 | 921 | ||
934 | for (i = 0; i < n_history; i++) { | 922 | for (i = 0; i < state->cnt_history; i++) { |
935 | fprintf(fp, "%s\n", history[i]); | 923 | fprintf(fp, "%s\n", state->history[i]); |
936 | } | 924 | } |
937 | fclose(fp); | 925 | fclose(fp); |
938 | } | 926 | } |
939 | } | 927 | } |
928 | #else | ||
929 | #define load_history(a) ((void)0) | ||
930 | #define save_history(a) ((void)0) | ||
940 | #endif /* FEATURE_COMMAND_SAVEHISTORY */ | 931 | #endif /* FEATURE_COMMAND_SAVEHISTORY */ |
941 | 932 | ||
942 | #endif /* MAX_HISTORY > 0 */ | 933 | static void remember_in_history(const char *str) |
934 | { | ||
935 | int i; | ||
936 | |||
937 | if (!(state->flags & DO_HISTORY)) | ||
938 | return; | ||
939 | |||
940 | i = state->cnt_history; | ||
941 | free(state->history[MAX_HISTORY]); | ||
942 | state->history[MAX_HISTORY] = NULL; | ||
943 | /* After max history, remove the oldest command */ | ||
944 | if (i >= MAX_HISTORY) { | ||
945 | free(state->history[0]); | ||
946 | for (i = 0; i < MAX_HISTORY-1; i++) | ||
947 | state->history[i] = state->history[i+1]; | ||
948 | } | ||
949 | // Maybe "if (!i || strcmp(history[i-1], command) != 0) ..." | ||
950 | // (i.e. do not save dups?) | ||
951 | state->history[i++] = xstrdup(str); | ||
952 | state->cur_history = i; | ||
953 | state->cnt_history = i; | ||
954 | if (state->flags & SAVE_HISTORY) | ||
955 | save_history(state->hist_file); | ||
956 | USE_FEATURE_SH_FANCY_PROMPT(num_ok_lines++;) | ||
957 | } | ||
958 | |||
959 | #else /* MAX_HISTORY == 0 */ | ||
960 | #define remember_in_history(a) ((void)0) | ||
961 | #endif /* MAX_HISTORY */ | ||
943 | 962 | ||
944 | 963 | ||
945 | /* | 964 | /* |
@@ -960,13 +979,6 @@ void save_history(const char *tofile) | |||
960 | */ | 979 | */ |
961 | 980 | ||
962 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | 981 | #if ENABLE_FEATURE_COMMAND_EDITING_VI |
963 | static int vi_mode; | ||
964 | |||
965 | void setvimode(int viflag) | ||
966 | { | ||
967 | vi_mode = viflag; | ||
968 | } | ||
969 | |||
970 | static void | 982 | static void |
971 | vi_Word_motion(char *command, int eat) | 983 | vi_Word_motion(char *command, int eat) |
972 | { | 984 | { |
@@ -1058,13 +1070,11 @@ vi_back_motion(char *command) | |||
1058 | input_backward(1); | 1070 | input_backward(1); |
1059 | } | 1071 | } |
1060 | } | 1072 | } |
1061 | #else | ||
1062 | enum { vi_mode = 0 }; | ||
1063 | #endif | 1073 | #endif |
1064 | 1074 | ||
1065 | 1075 | ||
1066 | /* | 1076 | /* |
1067 | * cmdedit_read_input and its helpers | 1077 | * read_line_input and its helpers |
1068 | */ | 1078 | */ |
1069 | 1079 | ||
1070 | #if !ENABLE_FEATURE_SH_FANCY_PROMPT | 1080 | #if !ENABLE_FEATURE_SH_FANCY_PROMPT |
@@ -1190,7 +1200,7 @@ static void parse_prompt(const char *prmt_ptr) | |||
1190 | cmdedit_prmt_len += cur_prmt_len; | 1200 | cmdedit_prmt_len += cur_prmt_len; |
1191 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); | 1201 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); |
1192 | } | 1202 | } |
1193 | if (pwd_buf!=(char *)bb_msg_unknown) | 1203 | if (pwd_buf != (char *)bb_msg_unknown) |
1194 | free(pwd_buf); | 1204 | free(pwd_buf); |
1195 | cmdedit_prompt = prmt_mem_ptr; | 1205 | cmdedit_prompt = prmt_mem_ptr; |
1196 | put_prompt(); | 1206 | put_prompt(); |
@@ -1217,7 +1227,7 @@ static void cmdedit_setwidth(unsigned w, int redraw_flg) | |||
1217 | /* new y for current cursor */ | 1227 | /* new y for current cursor */ |
1218 | int new_y = (cursor + cmdedit_prmt_len) / w; | 1228 | int new_y = (cursor + cmdedit_prmt_len) / w; |
1219 | /* redraw */ | 1229 | /* redraw */ |
1220 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor); | 1230 | redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), command_len - cursor); |
1221 | fflush(stdout); | 1231 | fflush(stdout); |
1222 | } | 1232 | } |
1223 | } | 1233 | } |
@@ -1275,9 +1285,10 @@ static void cmdedit_init(void) | |||
1275 | #undef CTRL | 1285 | #undef CTRL |
1276 | #define CTRL(a) ((a) & ~0x40) | 1286 | #define CTRL(a) ((a) & ~0x40) |
1277 | 1287 | ||
1278 | 1288 | int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *st) | |
1279 | int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | ||
1280 | { | 1289 | { |
1290 | static const int null_flags; | ||
1291 | |||
1281 | int lastWasTab = FALSE; | 1292 | int lastWasTab = FALSE; |
1282 | unsigned int ic; | 1293 | unsigned int ic; |
1283 | unsigned char c; | 1294 | unsigned char c; |
@@ -1286,18 +1297,28 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1286 | smallint vi_cmdmode = 0; | 1297 | smallint vi_cmdmode = 0; |
1287 | smalluint prevc; | 1298 | smalluint prevc; |
1288 | #endif | 1299 | #endif |
1300 | |||
1301 | // FIXME: audit & improve this | ||
1302 | if (maxsize > BUFSIZ) | ||
1303 | maxsize = BUFSIZ; | ||
1304 | |||
1305 | /* With null flags, no other fields are ever used */ | ||
1306 | state = st ? st : (line_input_t*) &null_flags; | ||
1307 | if (state->flags & SAVE_HISTORY) | ||
1308 | load_history(state->hist_file); | ||
1309 | |||
1289 | /* prepare before init handlers */ | 1310 | /* prepare before init handlers */ |
1290 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | 1311 | cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ |
1291 | len = 0; | 1312 | command_len = 0; |
1292 | command_ps = command; | 1313 | command_ps = command; |
1293 | command[0] = '\0'; | 1314 | command[0] = '\0'; |
1294 | 1315 | ||
1295 | getTermSettings(0, (void *) &initial_settings); | 1316 | getTermSettings(0, (void *) &initial_settings); |
1296 | memcpy(&new_settings, &initial_settings, sizeof(struct termios)); | 1317 | memcpy(&new_settings, &initial_settings, sizeof(new_settings)); |
1297 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ | 1318 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ |
1298 | /* Turn off echoing and CTRL-C, so we can trap it */ | 1319 | /* Turn off echoing and CTRL-C, so we can trap it */ |
1299 | new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); | 1320 | new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); |
1300 | /* Hmm, in linux c_cc[] not parsed if set ~ICANON */ | 1321 | /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ |
1301 | new_settings.c_cc[VMIN] = 1; | 1322 | new_settings.c_cc[VMIN] = 1; |
1302 | new_settings.c_cc[VTIME] = 0; | 1323 | new_settings.c_cc[VTIME] = 0; |
1303 | /* Turn off CTRL-C, so we can trap it */ | 1324 | /* Turn off CTRL-C, so we can trap it */ |
@@ -1354,34 +1375,18 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1354 | vi_case(CTRL('C')|vbit:) | 1375 | vi_case(CTRL('C')|vbit:) |
1355 | /* Control-c -- stop gathering input */ | 1376 | /* Control-c -- stop gathering input */ |
1356 | goto_new_line(); | 1377 | goto_new_line(); |
1357 | #if !ENABLE_ASH | 1378 | command_len = 0; |
1358 | command[0] = '\0'; | 1379 | break_out = -1; /* "do not append '\n'" */ |
1359 | len = 0; | ||
1360 | lastWasTab = FALSE; | ||
1361 | put_prompt(); | ||
1362 | #else | ||
1363 | len = 0; | ||
1364 | break_out = -1; /* to control traps */ | ||
1365 | #endif | ||
1366 | break; | 1380 | break; |
1367 | case CTRL('D'): | 1381 | case CTRL('D'): |
1368 | /* Control-d -- Delete one character, or exit | 1382 | /* Control-d -- Delete one character, or exit |
1369 | * if the len=0 and no chars to delete */ | 1383 | * if the len=0 and no chars to delete */ |
1370 | if (len == 0) { | 1384 | if (command_len == 0) { |
1371 | errno = 0; | 1385 | errno = 0; |
1372 | prepare_to_die: | 1386 | prepare_to_die: |
1373 | // So, our API depends on whether we have ash compiled in or not? Crap... | ||
1374 | #if !ENABLE_ASH | ||
1375 | printf("exit"); | ||
1376 | goto_new_line(); | ||
1377 | /* cmdedit_reset_term() called in atexit */ | ||
1378 | // FIXME. this is definitely not good | ||
1379 | exit(EXIT_SUCCESS); | ||
1380 | #else | ||
1381 | /* to control stopped jobs */ | 1387 | /* to control stopped jobs */ |
1382 | break_out = len = -1; | 1388 | break_out = command_len = -1; |
1383 | break; | 1389 | break; |
1384 | #endif | ||
1385 | } | 1390 | } |
1386 | input_delete(0); | 1391 | input_delete(0); |
1387 | break; | 1392 | break; |
@@ -1407,23 +1412,21 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1407 | break; | 1412 | break; |
1408 | 1413 | ||
1409 | case '\t': | 1414 | case '\t': |
1410 | #if ENABLE_FEATURE_COMMAND_TAB_COMPLETION | ||
1411 | input_tab(&lastWasTab); | 1415 | input_tab(&lastWasTab); |
1412 | #endif | ||
1413 | break; | 1416 | break; |
1414 | 1417 | ||
1415 | #if ENABLE_FEATURE_EDITING_FANCY_KEYS | 1418 | #if ENABLE_FEATURE_EDITING_FANCY_KEYS |
1416 | case CTRL('K'): | 1419 | case CTRL('K'): |
1417 | /* Control-k -- clear to end of line */ | 1420 | /* Control-k -- clear to end of line */ |
1418 | command[cursor] = 0; | 1421 | command[cursor] = 0; |
1419 | len = cursor; | 1422 | command_len = cursor; |
1420 | printf("\033[J"); | 1423 | printf("\033[J"); |
1421 | break; | 1424 | break; |
1422 | case CTRL('L'): | 1425 | case CTRL('L'): |
1423 | vi_case(CTRL('L')|vbit:) | 1426 | vi_case(CTRL('L')|vbit:) |
1424 | /* Control-l -- clear screen */ | 1427 | /* Control-l -- clear screen */ |
1425 | printf("\033[H"); | 1428 | printf("\033[H"); |
1426 | redraw(0, len - cursor); | 1429 | redraw(0, command_len - cursor); |
1427 | break; | 1430 | break; |
1428 | #endif | 1431 | #endif |
1429 | 1432 | ||
@@ -1439,12 +1442,11 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1439 | vi_case(CTRL('P')|vbit:) | 1442 | vi_case(CTRL('P')|vbit:) |
1440 | vi_case('k'|vbit:) | 1443 | vi_case('k'|vbit:) |
1441 | /* Control-p -- Get previous command from history */ | 1444 | /* Control-p -- Get previous command from history */ |
1442 | if (cur_history > 0) { | 1445 | if ((state->flags & DO_HISTORY) && state->cur_history > 0) { |
1443 | get_previous_history(); | 1446 | get_previous_history(); |
1444 | goto rewrite_line; | 1447 | goto rewrite_line; |
1445 | } else { | ||
1446 | beep(); | ||
1447 | } | 1448 | } |
1449 | beep(); | ||
1448 | break; | 1450 | break; |
1449 | #endif | 1451 | #endif |
1450 | 1452 | ||
@@ -1454,7 +1456,8 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1454 | /* Control-U -- Clear line before cursor */ | 1456 | /* Control-U -- Clear line before cursor */ |
1455 | if (cursor) { | 1457 | if (cursor) { |
1456 | strcpy(command, command + cursor); | 1458 | strcpy(command, command + cursor); |
1457 | redraw(cmdedit_y, len -= cursor); | 1459 | command_len -= cursor; |
1460 | redraw(cmdedit_y, command_len); | ||
1458 | } | 1461 | } |
1459 | break; | 1462 | break; |
1460 | #endif | 1463 | #endif |
@@ -1571,7 +1574,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1571 | break; | 1574 | break; |
1572 | case '$': /* "d$", "c$" */ | 1575 | case '$': /* "d$", "c$" */ |
1573 | clear_to_eol: | 1576 | clear_to_eol: |
1574 | while (cursor < len) | 1577 | while (cursor < command_len) |
1575 | input_delete(1); | 1578 | input_delete(1); |
1576 | break; | 1579 | break; |
1577 | } | 1580 | } |
@@ -1599,7 +1602,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1599 | case '\x1b': /* ESC */ | 1602 | case '\x1b': /* ESC */ |
1600 | 1603 | ||
1601 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | 1604 | #if ENABLE_FEATURE_COMMAND_EDITING_VI |
1602 | if (vi_mode) { | 1605 | if (state->flags & VI_MODE) { |
1603 | /* ESC: insert mode --> command mode */ | 1606 | /* ESC: insert mode --> command mode */ |
1604 | vi_cmdmode = 1; | 1607 | vi_cmdmode = 1; |
1605 | input_backward(1); | 1608 | input_backward(1); |
@@ -1634,7 +1637,7 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1634 | #if MAX_HISTORY > 0 | 1637 | #if MAX_HISTORY > 0 |
1635 | case 'A': | 1638 | case 'A': |
1636 | /* Up Arrow -- Get previous command from history */ | 1639 | /* Up Arrow -- Get previous command from history */ |
1637 | if (cur_history > 0) { | 1640 | if ((state->flags & DO_HISTORY) && state->cur_history > 0) { |
1638 | get_previous_history(); | 1641 | get_previous_history(); |
1639 | goto rewrite_line; | 1642 | goto rewrite_line; |
1640 | } | 1643 | } |
@@ -1647,9 +1650,9 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1647 | rewrite_line: | 1650 | rewrite_line: |
1648 | /* Rewrite the line with the selected history item */ | 1651 | /* Rewrite the line with the selected history item */ |
1649 | /* change command */ | 1652 | /* change command */ |
1650 | len = strlen(strcpy(command, history[cur_history])); | 1653 | command_len = strlen(strcpy(command, state->history[state->cur_history])); |
1651 | /* redraw and go to eol (bol, in vi */ | 1654 | /* redraw and go to eol (bol, in vi */ |
1652 | redraw(cmdedit_y, vi_mode ? 9999 : 0); | 1655 | redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); |
1653 | break; | 1656 | break; |
1654 | #endif | 1657 | #endif |
1655 | case 'C': | 1658 | case 'C': |
@@ -1700,18 +1703,18 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1700 | if (!Isprint(c)) /* Skip non-printable characters */ | 1703 | if (!Isprint(c)) /* Skip non-printable characters */ |
1701 | break; | 1704 | break; |
1702 | 1705 | ||
1703 | if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */ | 1706 | if (command_len >= (maxsize - 2)) /* Need to leave space for enter */ |
1704 | break; | 1707 | break; |
1705 | 1708 | ||
1706 | len++; | 1709 | command_len++; |
1707 | if (cursor == (len - 1)) { /* Append if at the end of the line */ | 1710 | if (cursor == (command_len - 1)) { /* Append if at the end of the line */ |
1708 | command[cursor] = c; | 1711 | command[cursor] = c; |
1709 | command[cursor+1] = '\0'; | 1712 | command[cursor+1] = '\0'; |
1710 | cmdedit_set_out_char(' '); | 1713 | cmdedit_set_out_char(' '); |
1711 | } else { /* Insert otherwise */ | 1714 | } else { /* Insert otherwise */ |
1712 | int sc = cursor; | 1715 | int sc = cursor; |
1713 | 1716 | ||
1714 | memmove(command + sc + 1, command + sc, len - sc); | 1717 | memmove(command + sc + 1, command + sc, command_len - sc); |
1715 | command[sc] = c; | 1718 | command[sc] = c; |
1716 | sc++; | 1719 | sc++; |
1717 | /* rewrite from cursor */ | 1720 | /* rewrite from cursor */ |
@@ -1728,35 +1731,12 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1728 | lastWasTab = FALSE; | 1731 | lastWasTab = FALSE; |
1729 | } | 1732 | } |
1730 | 1733 | ||
1731 | #if MAX_HISTORY > 0 | 1734 | if (command_len > 0) |
1732 | /* Handle command history log */ | 1735 | remember_in_history(command); |
1733 | /* cleanup may be saved current command line */ | ||
1734 | if (len > 0) { | ||
1735 | int i = n_history; | ||
1736 | |||
1737 | free(history[MAX_HISTORY]); | ||
1738 | history[MAX_HISTORY] = NULL; | ||
1739 | /* After max history, remove the oldest command */ | ||
1740 | if (i >= MAX_HISTORY) { | ||
1741 | free(history[0]); | ||
1742 | for (i = 0; i < MAX_HISTORY-1; i++) | ||
1743 | history[i] = history[i+1]; | ||
1744 | } | ||
1745 | // Maybe "if (!i || strcmp(history[i-1], command) != 0) ..." | ||
1746 | // (i.e. do not save dups?) | ||
1747 | history[i++] = xstrdup(command); | ||
1748 | cur_history = i; | ||
1749 | n_history = i; | ||
1750 | USE_FEATURE_SH_FANCY_PROMPT(num_ok_lines++;) | ||
1751 | } | ||
1752 | #else /* MAX_HISTORY == 0 */ | ||
1753 | /* dont put empty line */ | ||
1754 | USE_FEATURE_SH_FANCY_PROMPT(if (len > 0) num_ok_lines++;) | ||
1755 | #endif /* MAX_HISTORY */ | ||
1756 | 1736 | ||
1757 | if (break_out > 0) { | 1737 | if (break_out > 0) { |
1758 | command[len++] = '\n'; | 1738 | command[command_len++] = '\n'; |
1759 | command[len] = '\0'; | 1739 | command[command_len] = '\0'; |
1760 | } | 1740 | } |
1761 | 1741 | ||
1762 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION | 1742 | #if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION |
@@ -1764,11 +1744,29 @@ int cmdedit_read_input(char *prompt, char command[BUFSIZ]) | |||
1764 | #endif | 1744 | #endif |
1765 | 1745 | ||
1766 | #if ENABLE_FEATURE_SH_FANCY_PROMPT | 1746 | #if ENABLE_FEATURE_SH_FANCY_PROMPT |
1767 | free(cmdedit_prompt); | 1747 | free((char*)cmdedit_prompt); |
1768 | #endif | 1748 | #endif |
1769 | /* restore initial_settings and SIGWINCH handler */ | 1749 | /* restore initial_settings and SIGWINCH handler */ |
1770 | cmdedit_reset_term(); | 1750 | cmdedit_reset_term(); |
1771 | return len; | 1751 | return command_len; |
1752 | } | ||
1753 | |||
1754 | line_input_t *new_line_input_t(int flags) | ||
1755 | { | ||
1756 | line_input_t *n = xzalloc(sizeof(*n)); | ||
1757 | n->flags = flags; | ||
1758 | return n; | ||
1759 | } | ||
1760 | |||
1761 | #else | ||
1762 | |||
1763 | #undef read_line_input | ||
1764 | int read_line_input(const char* prompt, char* command, int maxsize) | ||
1765 | { | ||
1766 | fputs(prompt, stdout); | ||
1767 | fflush(stdout); | ||
1768 | fgets(command, maxsize, stdin); | ||
1769 | return strlen(command); | ||
1772 | } | 1770 | } |
1773 | 1771 | ||
1774 | #endif /* FEATURE_COMMAND_EDITING */ | 1772 | #endif /* FEATURE_COMMAND_EDITING */ |
@@ -1801,13 +1799,13 @@ int main(int argc, char **argv) | |||
1801 | #endif | 1799 | #endif |
1802 | while (1) { | 1800 | while (1) { |
1803 | int l; | 1801 | int l; |
1804 | l = cmdedit_read_input(prompt, buff); | 1802 | l = read_line_input(prompt, buff); |
1805 | if (l <= 0 || buff[l-1] != '\n') | 1803 | if (l <= 0 || buff[l-1] != '\n') |
1806 | break; | 1804 | break; |
1807 | buff[l-1] = 0; | 1805 | buff[l-1] = 0; |
1808 | printf("*** cmdedit_read_input() returned line =%s=\n", buff); | 1806 | printf("*** read_line_input() returned line =%s=\n", buff); |
1809 | } | 1807 | } |
1810 | printf("*** cmdedit_read_input() detect ^D\n"); | 1808 | printf("*** read_line_input() detect ^D\n"); |
1811 | return 0; | 1809 | return 0; |
1812 | } | 1810 | } |
1813 | 1811 | ||
diff --git a/shell/cmdedit.h b/shell/cmdedit.h index 4a32cf63e..7af2f75fb 100644 --- a/shell/cmdedit.h +++ b/shell/cmdedit.h | |||
@@ -1,20 +1 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | /* TO DELETE */ | |
2 | #ifndef CMDEDIT_H | ||
3 | #define CMDEDIT_H | ||
4 | |||
5 | int cmdedit_read_input(char* promptStr, char* command); | ||
6 | |||
7 | #if ENABLE_ASH | ||
8 | extern const char *cmdedit_path_lookup; | ||
9 | #endif | ||
10 | |||
11 | #if ENABLE_FEATURE_COMMAND_SAVEHISTORY | ||
12 | void load_history(const char *fromfile); | ||
13 | void save_history(const char *tofile); | ||
14 | #endif | ||
15 | |||
16 | #if ENABLE_FEATURE_COMMAND_EDITING_VI | ||
17 | void setvimode(int viflag); | ||
18 | #endif | ||
19 | |||
20 | #endif /* CMDEDIT_H */ | ||
diff --git a/shell/hush.c b/shell/hush.c index 8f2dc80f2..2c88238ae 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -98,7 +98,6 @@ | |||
98 | /* #include <dmalloc.h> */ | 98 | /* #include <dmalloc.h> */ |
99 | /* #define DEBUG_SHELL */ | 99 | /* #define DEBUG_SHELL */ |
100 | 100 | ||
101 | #include "cmdedit.h" | ||
102 | 101 | ||
103 | #define SPECIAL_VAR_SYMBOL 03 | 102 | #define SPECIAL_VAR_SYMBOL 03 |
104 | #define FLAG_EXIT_FROM_LOOP 1 | 103 | #define FLAG_EXIT_FROM_LOOP 1 |
@@ -883,20 +882,24 @@ static void setup_prompt_string(int promptmode, char **prompt_str) | |||
883 | debug_printf("result %s\n",*prompt_str); | 882 | debug_printf("result %s\n",*prompt_str); |
884 | } | 883 | } |
885 | 884 | ||
885 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
886 | static line_input_t *line_input_state; | ||
887 | #endif | ||
888 | |||
886 | static void get_user_input(struct in_str *i) | 889 | static void get_user_input(struct in_str *i) |
887 | { | 890 | { |
888 | char *prompt_str; | 891 | char *prompt_str; |
889 | static char the_command[BUFSIZ]; | 892 | static char the_command[BUFSIZ]; |
890 | 893 | ||
891 | setup_prompt_string(i->promptmode, &prompt_str); | 894 | setup_prompt_string(i->promptmode, &prompt_str); |
892 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 895 | #if ENABLE_FEATURE_COMMAND_EDITING |
893 | /* | 896 | /* |
894 | ** enable command line editing only while a command line | 897 | ** enable command line editing only while a command line |
895 | ** is actually being read; otherwise, we'll end up bequeathing | 898 | ** is actually being read; otherwise, we'll end up bequeathing |
896 | ** atexit() handlers and other unwanted stuff to our | 899 | ** atexit() handlers and other unwanted stuff to our |
897 | ** child processes (rob@sysgo.de) | 900 | ** child processes (rob@sysgo.de) |
898 | */ | 901 | */ |
899 | cmdedit_read_input(prompt_str, the_command); | 902 | read_line_input(prompt_str, the_command, BUFSIZ, line_input_state); |
900 | #else | 903 | #else |
901 | fputs(prompt_str, stdout); | 904 | fputs(prompt_str, stdout); |
902 | fflush(stdout); | 905 | fflush(stdout); |
@@ -2647,6 +2650,10 @@ int hush_main(int argc, char **argv) | |||
2647 | FILE *input; | 2650 | FILE *input; |
2648 | char **e = environ; | 2651 | char **e = environ; |
2649 | 2652 | ||
2653 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | ||
2654 | line_input_state = new_line_input_t(FOR_SHELL); | ||
2655 | #endif | ||
2656 | |||
2650 | /* XXX what should these be while sourcing /etc/profile? */ | 2657 | /* XXX what should these be while sourcing /etc/profile? */ |
2651 | global_argc = argc; | 2658 | global_argc = argc; |
2652 | global_argv = argv; | 2659 | global_argv = argv; |
diff --git a/shell/lash.c b/shell/lash.c index b2ccaf0a1..a09a9a9b1 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | #include "busybox.h" | 24 | #include "busybox.h" |
25 | #include <getopt.h> | 25 | #include <getopt.h> |
26 | #include "cmdedit.h" | ||
27 | |||
28 | #include <glob.h> | 26 | #include <glob.h> |
29 | #define expand_t glob_t | 27 | #define expand_t glob_t |
30 | 28 | ||
@@ -641,6 +639,10 @@ static inline void setup_prompt_string(char **prompt_str) | |||
641 | #endif | 639 | #endif |
642 | } | 640 | } |
643 | 641 | ||
642 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
643 | static line_input_t *line_input_state; | ||
644 | #endif | ||
645 | |||
644 | static int get_command(FILE * source, char *command) | 646 | static int get_command(FILE * source, char *command) |
645 | { | 647 | { |
646 | char *prompt_str; | 648 | char *prompt_str; |
@@ -659,14 +661,14 @@ static int get_command(FILE * source, char *command) | |||
659 | if (source == stdin) { | 661 | if (source == stdin) { |
660 | setup_prompt_string(&prompt_str); | 662 | setup_prompt_string(&prompt_str); |
661 | 663 | ||
662 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 664 | #if ENABLE_FEATURE_COMMAND_EDITING |
663 | /* | 665 | /* |
664 | ** enable command line editing only while a command line | 666 | ** enable command line editing only while a command line |
665 | ** is actually being read; otherwise, we'll end up bequeathing | 667 | ** is actually being read; otherwise, we'll end up bequeathing |
666 | ** atexit() handlers and other unwanted stuff to our | 668 | ** atexit() handlers and other unwanted stuff to our |
667 | ** child processes (rob@sysgo.de) | 669 | ** child processes (rob@sysgo.de) |
668 | */ | 670 | */ |
669 | cmdedit_read_input(prompt_str, command); | 671 | read_line_input(prompt_str, command, BUFSIZ, line_input_state); |
670 | return 0; | 672 | return 0; |
671 | #else | 673 | #else |
672 | fputs(prompt_str, stdout); | 674 | fputs(prompt_str, stdout); |
@@ -1505,6 +1507,10 @@ int lash_main(int argc_l, char **argv_l) | |||
1505 | argc = argc_l; | 1507 | argc = argc_l; |
1506 | argv = argv_l; | 1508 | argv = argv_l; |
1507 | 1509 | ||
1510 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
1511 | line_input_state = new_line_input_t(FOR_SHELL); | ||
1512 | #endif | ||
1513 | |||
1508 | /* These variables need re-initializing when recursing */ | 1514 | /* These variables need re-initializing when recursing */ |
1509 | last_jobid = 0; | 1515 | last_jobid = 0; |
1510 | close_me_list = NULL; | 1516 | close_me_list = NULL; |
diff --git a/shell/msh.c b/shell/msh.c index c88308f8f..8746e42bc 100644 --- a/shell/msh.c +++ b/shell/msh.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <setjmp.h> | 17 | #include <setjmp.h> |
18 | #include <sys/times.h> | 18 | #include <sys/times.h> |
19 | 19 | ||
20 | #include "cmdedit.h" | ||
21 | 20 | ||
22 | /*#define MSHDEBUG 1*/ | 21 | /*#define MSHDEBUG 1*/ |
23 | 22 | ||
@@ -777,7 +776,7 @@ void print_tree(struct op *head) | |||
777 | #endif /* MSHDEBUG */ | 776 | #endif /* MSHDEBUG */ |
778 | 777 | ||
779 | 778 | ||
780 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 779 | #if ENABLE_FEATURE_COMMAND_EDITING |
781 | static char *current_prompt; | 780 | static char *current_prompt; |
782 | #endif | 781 | #endif |
783 | 782 | ||
@@ -787,6 +786,10 @@ static char *current_prompt; | |||
787 | */ | 786 | */ |
788 | 787 | ||
789 | 788 | ||
789 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
790 | static line_input_t *line_input_state; | ||
791 | #endif | ||
792 | |||
790 | int msh_main(int argc, char **argv) | 793 | int msh_main(int argc, char **argv) |
791 | { | 794 | { |
792 | int f; | 795 | int f; |
@@ -795,6 +798,10 @@ int msh_main(int argc, char **argv) | |||
795 | char *name, **ap; | 798 | char *name, **ap; |
796 | int (*iof) (struct ioarg *); | 799 | int (*iof) (struct ioarg *); |
797 | 800 | ||
801 | #if ENABLE_FEATURE_COMMAND_EDITING | ||
802 | line_input_state = new_line_input_t(FOR_SHELL); | ||
803 | #endif | ||
804 | |||
798 | DBGPRINTF(("MSH_MAIN: argc %d, environ %p\n", argc, environ)); | 805 | DBGPRINTF(("MSH_MAIN: argc %d, environ %p\n", argc, environ)); |
799 | 806 | ||
800 | initarea(); | 807 | initarea(); |
@@ -964,7 +971,7 @@ int msh_main(int argc, char **argv) | |||
964 | 971 | ||
965 | for (;;) { | 972 | for (;;) { |
966 | if (interactive && e.iop <= iostack) { | 973 | if (interactive && e.iop <= iostack) { |
967 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 974 | #if ENABLE_FEATURE_COMMAND_EDITING |
968 | current_prompt = prompt->value; | 975 | current_prompt = prompt->value; |
969 | #else | 976 | #else |
970 | prs(prompt->value); | 977 | prs(prompt->value); |
@@ -2371,7 +2378,7 @@ static int yylex(int cf) | |||
2371 | startl = 1; | 2378 | startl = 1; |
2372 | if (multiline || cf & CONTIN) { | 2379 | if (multiline || cf & CONTIN) { |
2373 | if (interactive && e.iop <= iostack) { | 2380 | if (interactive && e.iop <= iostack) { |
2374 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 2381 | #if ENABLE_FEATURE_COMMAND_EDITING |
2375 | current_prompt = cprompt->value; | 2382 | current_prompt = cprompt->value; |
2376 | #else | 2383 | #else |
2377 | prs(cprompt->value); | 2384 | prs(cprompt->value); |
@@ -2432,7 +2439,7 @@ static int collect(int c, int c1) | |||
2432 | return YYERRCODE; | 2439 | return YYERRCODE; |
2433 | } | 2440 | } |
2434 | if (interactive && c == '\n' && e.iop <= iostack) { | 2441 | if (interactive && c == '\n' && e.iop <= iostack) { |
2435 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 2442 | #if ENABLE_FEATURE_COMMAND_EDITING |
2436 | current_prompt = cprompt->value; | 2443 | current_prompt = cprompt->value; |
2437 | #else | 2444 | #else |
2438 | prs(cprompt->value); | 2445 | prs(cprompt->value); |
@@ -4666,7 +4673,7 @@ static int readc(void) | |||
4666 | return e.iop->prev = 0; | 4673 | return e.iop->prev = 0; |
4667 | } | 4674 | } |
4668 | if (interactive && e.iop == iostack + 1) { | 4675 | if (interactive && e.iop == iostack + 1) { |
4669 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 4676 | #if ENABLE_FEATURE_COMMAND_EDITING |
4670 | current_prompt = prompt->value; | 4677 | current_prompt = prompt->value; |
4671 | #else | 4678 | #else |
4672 | prs(prompt->value); | 4679 | prs(prompt->value); |
@@ -4898,13 +4905,13 @@ static int filechar(struct ioarg *ap) | |||
4898 | ap->afpos++; | 4905 | ap->afpos++; |
4899 | return *bp->bufp++ & 0177; | 4906 | return *bp->bufp++ & 0177; |
4900 | } | 4907 | } |
4901 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 4908 | #if ENABLE_FEATURE_COMMAND_EDITING |
4902 | if (interactive && isatty(ap->afile)) { | 4909 | if (interactive && isatty(ap->afile)) { |
4903 | static char mycommand[BUFSIZ]; | 4910 | static char mycommand[BUFSIZ]; |
4904 | static int position = 0, size = 0; | 4911 | static int position = 0, size = 0; |
4905 | 4912 | ||
4906 | while (size == 0 || position >= size) { | 4913 | while (size == 0 || position >= size) { |
4907 | cmdedit_read_input(current_prompt, mycommand); | 4914 | read_line_input(current_prompt, mycommand, BUFSIZ, line_input_state); |
4908 | size = strlen(mycommand); | 4915 | size = strlen(mycommand); |
4909 | position = 0; | 4916 | position = 0; |
4910 | } | 4917 | } |
@@ -4913,7 +4920,6 @@ static int filechar(struct ioarg *ap) | |||
4913 | return c; | 4920 | return c; |
4914 | } else | 4921 | } else |
4915 | #endif | 4922 | #endif |
4916 | |||
4917 | { | 4923 | { |
4918 | i = safe_read(ap->afile, &c, sizeof(c)); | 4924 | i = safe_read(ap->afile, &c, sizeof(c)); |
4919 | return i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0); | 4925 | return i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0); |
@@ -5150,7 +5156,7 @@ static void readhere(char **name, char *s, int ec) | |||
5150 | e.iobase = e.iop; | 5156 | e.iobase = e.iop; |
5151 | for (;;) { | 5157 | for (;;) { |
5152 | if (interactive && e.iop <= iostack) { | 5158 | if (interactive && e.iop <= iostack) { |
5153 | #ifdef CONFIG_FEATURE_COMMAND_EDITING | 5159 | #if ENABLE_FEATURE_COMMAND_EDITING |
5154 | current_prompt = cprompt->value; | 5160 | current_prompt = cprompt->value; |
5155 | #else | 5161 | #else |
5156 | prs(cprompt->value); | 5162 | prs(cprompt->value); |
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index cc6dfa57a..f15b9af91 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -202,7 +202,7 @@ static int get_boot(enum action what); | |||
202 | }) | 202 | }) |
203 | 203 | ||
204 | 204 | ||
205 | #define LINE_LENGTH 800 | 205 | #define LINE_LENGTH 80 |
206 | #define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \ | 206 | #define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \ |
207 | (n) * sizeof(struct partition))) | 207 | (n) * sizeof(struct partition))) |
208 | #define sector(s) ((s) & 0x3f) | 208 | #define sector(s) ((s) & 0x3f) |
@@ -291,16 +291,20 @@ write_part_table_flag(char *b) | |||
291 | static char line_buffer[LINE_LENGTH]; | 291 | static char line_buffer[LINE_LENGTH]; |
292 | static char *line_ptr; | 292 | static char *line_ptr; |
293 | 293 | ||
294 | /* read line; return 0 or first char */ | 294 | /* read line; return 0 or first printable char */ |
295 | static int | 295 | static int |
296 | read_line(void) | 296 | read_line(const char *prompt) |
297 | { | 297 | { |
298 | fflush(stdout); /* requested by niles@scyld.com */ | 298 | int sz; |
299 | |||
300 | sz = read_line_input(prompt, line_buffer, LINE_LENGTH, NULL); | ||
301 | if (sz <= 0) | ||
302 | exit(0); /* Ctrl-D or Ctrl-C */ | ||
303 | |||
304 | if (line_buffer[sz-1] == '\n') | ||
305 | line_buffer[--sz] = '\0'; | ||
306 | |||
299 | line_ptr = line_buffer; | 307 | line_ptr = line_buffer; |
300 | if (!fgets(line_buffer, LINE_LENGTH, stdin)) { | ||
301 | /* error or eof */ | ||
302 | bb_error_msg_and_die("\ngot EOF, exiting"); | ||
303 | } | ||
304 | while (*line_ptr && !isgraph(*line_ptr)) | 308 | while (*line_ptr && !isgraph(*line_ptr)) |
305 | line_ptr++; | 309 | line_ptr++; |
306 | return *line_ptr; | 310 | return *line_ptr; |
@@ -309,22 +313,19 @@ read_line(void) | |||
309 | static char | 313 | static char |
310 | read_nonempty(const char *mesg) | 314 | read_nonempty(const char *mesg) |
311 | { | 315 | { |
312 | do { | 316 | while (!read_line(mesg)) /* repeat */; |
313 | fputs(mesg, stdout); | ||
314 | } while (!read_line()); | ||
315 | return *line_ptr; | 317 | return *line_ptr; |
316 | } | 318 | } |
317 | 319 | ||
318 | static char | 320 | static char |
319 | read_maybe_empty(const char *mesg) | 321 | read_maybe_empty(const char *mesg) |
320 | { | 322 | { |
321 | fputs(mesg, stdout); | 323 | if (!read_line(mesg)) { |
322 | if (!read_line()) { | ||
323 | line_ptr = line_buffer; | 324 | line_ptr = line_buffer; |
324 | *line_ptr = '\n'; | 325 | line_ptr[0] = '\n'; |
325 | line_ptr[1] = 0; | 326 | line_ptr[1] = '\0'; |
326 | } | 327 | } |
327 | return *line_ptr; | 328 | return line_ptr[0]; |
328 | } | 329 | } |
329 | 330 | ||
330 | static int | 331 | static int |
@@ -469,9 +470,9 @@ static const struct systypes i386_sys_types[] = { | |||
469 | { "\x16" "Hidden FAT16" }, | 470 | { "\x16" "Hidden FAT16" }, |
470 | { "\x17" "Hidden HPFS/NTFS" }, | 471 | { "\x17" "Hidden HPFS/NTFS" }, |
471 | { "\x1b" "Hidden Win95 FAT32" }, | 472 | { "\x1b" "Hidden Win95 FAT32" }, |
472 | { "\x1c" "Hidden Win95 FAT32 (LBA)" }, | 473 | { "\x1c" "Hidden W95 FAT32 (LBA)" }, |
473 | { "\x1e" "Hidden Win95 FAT16 (LBA)" }, | 474 | { "\x1e" "Hidden W95 FAT16 (LBA)" }, |
474 | { "\x3c" "PartitionMagic recovery" }, | 475 | { "\x3c" "Part.Magic recovery" }, |
475 | { "\x41" "PPC PReP Boot" }, | 476 | { "\x41" "PPC PReP Boot" }, |
476 | { "\x42" "SFS" }, | 477 | { "\x42" "SFS" }, |
477 | { "\x63" "GNU HURD or SysV" }, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ | 478 | { "\x63" "GNU HURD or SysV" }, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */ |
@@ -485,7 +486,7 @@ static const struct systypes i386_sys_types[] = { | |||
485 | { "\x87" "NTFS volume set" }, | 486 | { "\x87" "NTFS volume set" }, |
486 | { "\x8e" "Linux LVM" }, | 487 | { "\x8e" "Linux LVM" }, |
487 | { "\x9f" "BSD/OS" }, /* BSDI */ | 488 | { "\x9f" "BSD/OS" }, /* BSDI */ |
488 | { "\xa0" "IBM Thinkpad hibernation" }, | 489 | { "\xa0" "Thinkpad hibernation" }, |
489 | { "\xa5" "FreeBSD" }, /* various BSD flavours */ | 490 | { "\xa5" "FreeBSD" }, /* various BSD flavours */ |
490 | { "\xa6" "OpenBSD" }, | 491 | { "\xa6" "OpenBSD" }, |
491 | { "\xa8" "Darwin UFS" }, | 492 | { "\xa8" "Darwin UFS" }, |
@@ -718,71 +719,61 @@ is_dos_partition(int t) | |||
718 | static void | 719 | static void |
719 | menu(void) | 720 | menu(void) |
720 | { | 721 | { |
722 | puts(_("Command Action")); | ||
721 | if (LABEL_IS_SUN) { | 723 | if (LABEL_IS_SUN) { |
722 | puts(_("Command action")); | 724 | puts(_("a\ttoggle a read only flag")); /* sun */ |
723 | puts(_("\ta\ttoggle a read only flag")); /* sun */ | 725 | puts(_("b\tedit bsd disklabel")); |
724 | puts(_("\tb\tedit bsd disklabel")); | 726 | puts(_("c\ttoggle the mountable flag")); /* sun */ |
725 | puts(_("\tc\ttoggle the mountable flag")); /* sun */ | 727 | puts(_("d\tdelete a partition")); |
726 | puts(_("\td\tdelete a partition")); | 728 | puts(_("l\tlist known partition types")); |
727 | puts(_("\tl\tlist known partition types")); | 729 | puts(_("n\tadd a new partition")); |
728 | puts(_("\tm\tprint this menu")); | 730 | puts(_("o\tcreate a new empty DOS partition table")); |
729 | puts(_("\tn\tadd a new partition")); | 731 | puts(_("p\tprint the partition table")); |
730 | puts(_("\to\tcreate a new empty DOS partition table")); | 732 | puts(_("q\tquit without saving changes")); |
731 | puts(_("\tp\tprint the partition table")); | 733 | puts(_("s\tcreate a new empty Sun disklabel")); /* sun */ |
732 | puts(_("\tq\tquit without saving changes")); | 734 | puts(_("t\tchange a partition's system id")); |
733 | puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ | 735 | puts(_("u\tchange display/entry units")); |
734 | puts(_("\tt\tchange a partition's system id")); | 736 | puts(_("v\tverify the partition table")); |
735 | puts(_("\tu\tchange display/entry units")); | 737 | puts(_("w\twrite table to disk and exit")); |
736 | puts(_("\tv\tverify the partition table")); | ||
737 | puts(_("\tw\twrite table to disk and exit")); | ||
738 | #if ENABLE_FEATURE_FDISK_ADVANCED | 738 | #if ENABLE_FEATURE_FDISK_ADVANCED |
739 | puts(_("\tx\textra functionality (experts only)")); | 739 | puts(_("x\textra functionality (experts only)")); |
740 | #endif | 740 | #endif |
741 | } else | 741 | } else if (LABEL_IS_SGI) { |
742 | if (LABEL_IS_SGI) { | 742 | puts(_("a\tselect bootable partition")); /* sgi flavour */ |
743 | puts(_("Command action")); | 743 | puts(_("b\tedit bootfile entry")); /* sgi */ |
744 | puts(_("\ta\tselect bootable partition")); /* sgi flavour */ | 744 | puts(_("c\tselect sgi swap partition")); /* sgi flavour */ |
745 | puts(_("\tb\tedit bootfile entry")); /* sgi */ | 745 | puts(_("d\tdelete a partition")); |
746 | puts(_("\tc\tselect sgi swap partition")); /* sgi flavour */ | 746 | puts(_("l\tlist known partition types")); |
747 | puts(_("\td\tdelete a partition")); | 747 | puts(_("n\tadd a new partition")); |
748 | puts(_("\tl\tlist known partition types")); | 748 | puts(_("o\tcreate a new empty DOS partition table")); |
749 | puts(_("\tm\tprint this menu")); | 749 | puts(_("p\tprint the partition table")); |
750 | puts(_("\tn\tadd a new partition")); | 750 | puts(_("q\tquit without saving changes")); |
751 | puts(_("\to\tcreate a new empty DOS partition table")); | 751 | puts(_("s\tcreate a new empty Sun disklabel")); /* sun */ |
752 | puts(_("\tp\tprint the partition table")); | 752 | puts(_("t\tchange a partition's system id")); |
753 | puts(_("\tq\tquit without saving changes")); | 753 | puts(_("u\tchange display/entry units")); |
754 | puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ | 754 | puts(_("v\tverify the partition table")); |
755 | puts(_("\tt\tchange a partition's system id")); | 755 | puts(_("w\twrite table to disk and exit")); |
756 | puts(_("\tu\tchange display/entry units")); | 756 | } else if (LABEL_IS_AIX) { |
757 | puts(_("\tv\tverify the partition table")); | 757 | puts(_("o\tcreate a new empty DOS partition table")); |
758 | puts(_("\tw\twrite table to disk and exit")); | 758 | puts(_("q\tquit without saving changes")); |
759 | } else | 759 | puts(_("s\tcreate a new empty Sun disklabel")); /* sun */ |
760 | if (LABEL_IS_AIX) { | 760 | } else { |
761 | puts(_("Command action")); | 761 | puts(_("a\ttoggle a bootable flag")); |
762 | puts(_("\tm\tprint this menu")); | 762 | puts(_("b\tedit bsd disklabel")); |
763 | puts(_("\to\tcreate a new empty DOS partition table")); | 763 | puts(_("c\ttoggle the dos compatibility flag")); |
764 | puts(_("\tq\tquit without saving changes")); | 764 | puts(_("d\tdelete a partition")); |
765 | puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ | 765 | puts(_("l\tlist known partition types")); |
766 | } else | 766 | puts(_("n\tadd a new partition")); |
767 | { | 767 | puts(_("o\tcreate a new empty DOS partition table")); |
768 | puts(_("Command action")); | 768 | puts(_("p\tprint the partition table")); |
769 | puts(_("\ta\ttoggle a bootable flag")); | 769 | puts(_("q\tquit without saving changes")); |
770 | puts(_("\tb\tedit bsd disklabel")); | 770 | puts(_("s\tcreate a new empty Sun disklabel")); /* sun */ |
771 | puts(_("\tc\ttoggle the dos compatibility flag")); | 771 | puts(_("t\tchange a partition's system id")); |
772 | puts(_("\td\tdelete a partition")); | 772 | puts(_("u\tchange display/entry units")); |
773 | puts(_("\tl\tlist known partition types")); | 773 | puts(_("v\tverify the partition table")); |
774 | puts(_("\tm\tprint this menu")); | 774 | puts(_("w\twrite table to disk and exit")); |
775 | puts(_("\tn\tadd a new partition")); | ||
776 | puts(_("\to\tcreate a new empty DOS partition table")); | ||
777 | puts(_("\tp\tprint the partition table")); | ||
778 | puts(_("\tq\tquit without saving changes")); | ||
779 | puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */ | ||
780 | puts(_("\tt\tchange a partition's system id")); | ||
781 | puts(_("\tu\tchange display/entry units")); | ||
782 | puts(_("\tv\tverify the partition table")); | ||
783 | puts(_("\tw\twrite table to disk and exit")); | ||
784 | #if ENABLE_FEATURE_FDISK_ADVANCED | 775 | #if ENABLE_FEATURE_FDISK_ADVANCED |
785 | puts(_("\tx\textra functionality (experts only)")); | 776 | puts(_("x\textra functionality (experts only)")); |
786 | #endif | 777 | #endif |
787 | } | 778 | } |
788 | } | 779 | } |
@@ -793,73 +784,64 @@ menu(void) | |||
793 | static void | 784 | static void |
794 | xmenu(void) | 785 | xmenu(void) |
795 | { | 786 | { |
787 | puts(_("Command Action")); | ||
796 | if (LABEL_IS_SUN) { | 788 | if (LABEL_IS_SUN) { |
797 | puts(_("Command action")); | 789 | puts(_("a\tchange number of alternate cylinders")); /*sun*/ |
798 | puts(_("\ta\tchange number of alternate cylinders")); /*sun*/ | 790 | puts(_("c\tchange number of cylinders")); |
799 | puts(_("\tc\tchange number of cylinders")); | 791 | puts(_("d\tprint the raw data in the partition table")); |
800 | puts(_("\td\tprint the raw data in the partition table")); | 792 | puts(_("e\tchange number of extra sectors per cylinder"));/*sun*/ |
801 | puts(_("\te\tchange number of extra sectors per cylinder"));/*sun*/ | 793 | puts(_("h\tchange number of heads")); |
802 | puts(_("\th\tchange number of heads")); | 794 | puts(_("i\tchange interleave factor")); /*sun*/ |
803 | puts(_("\ti\tchange interleave factor")); /*sun*/ | 795 | puts(_("o\tchange rotation speed (rpm)")); /*sun*/ |
804 | puts(_("\to\tchange rotation speed (rpm)")); /*sun*/ | 796 | puts(_("p\tprint the partition table")); |
805 | puts(_("\tm\tprint this menu")); | 797 | puts(_("q\tquit without saving changes")); |
806 | puts(_("\tp\tprint the partition table")); | 798 | puts(_("r\treturn to main menu")); |
807 | puts(_("\tq\tquit without saving changes")); | 799 | puts(_("s\tchange number of sectors/track")); |
808 | puts(_("\tr\treturn to main menu")); | 800 | puts(_("v\tverify the partition table")); |
809 | puts(_("\ts\tchange number of sectors/track")); | 801 | puts(_("w\twrite table to disk and exit")); |
810 | puts(_("\tv\tverify the partition table")); | 802 | puts(_("y\tchange number of physical cylinders")); /*sun*/ |
811 | puts(_("\tw\twrite table to disk and exit")); | 803 | } else if (LABEL_IS_SGI) { |
812 | puts(_("\ty\tchange number of physical cylinders")); /*sun*/ | 804 | puts(_("b\tmove beginning of data in a partition")); /* !sun */ |
813 | } else | 805 | puts(_("c\tchange number of cylinders")); |
814 | if (LABEL_IS_SGI) { | 806 | puts(_("d\tprint the raw data in the partition table")); |
815 | puts(_("Command action")); | 807 | puts(_("e\tlist extended partitions")); /* !sun */ |
816 | puts(_("\tb\tmove beginning of data in a partition")); /* !sun */ | 808 | puts(_("g\tcreate an IRIX (SGI) partition table"));/* sgi */ |
817 | puts(_("\tc\tchange number of cylinders")); | 809 | puts(_("h\tchange number of heads")); |
818 | puts(_("\td\tprint the raw data in the partition table")); | 810 | puts(_("p\tprint the partition table")); |
819 | puts(_("\te\tlist extended partitions")); /* !sun */ | 811 | puts(_("q\tquit without saving changes")); |
820 | puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */ | 812 | puts(_("r\treturn to main menu")); |
821 | puts(_("\th\tchange number of heads")); | 813 | puts(_("s\tchange number of sectors/track")); |
822 | puts(_("\tm\tprint this menu")); | 814 | puts(_("v\tverify the partition table")); |
823 | puts(_("\tp\tprint the partition table")); | 815 | puts(_("w\twrite table to disk and exit")); |
824 | puts(_("\tq\tquit without saving changes")); | 816 | } else if (LABEL_IS_AIX) { |
825 | puts(_("\tr\treturn to main menu")); | 817 | puts(_("b\tmove beginning of data in a partition")); /* !sun */ |
826 | puts(_("\ts\tchange number of sectors/track")); | 818 | puts(_("c\tchange number of cylinders")); |
827 | puts(_("\tv\tverify the partition table")); | 819 | puts(_("d\tprint the raw data in the partition table")); |
828 | puts(_("\tw\twrite table to disk and exit")); | 820 | puts(_("e\tlist extended partitions")); /* !sun */ |
829 | } else | 821 | puts(_("g\tcreate an IRIX (SGI) partition table"));/* sgi */ |
830 | if (LABEL_IS_AIX) { | 822 | puts(_("h\tchange number of heads")); |
831 | puts(_("Command action")); | 823 | puts(_("p\tprint the partition table")); |
832 | puts(_("\tb\tmove beginning of data in a partition")); /* !sun */ | 824 | puts(_("q\tquit without saving changes")); |
833 | puts(_("\tc\tchange number of cylinders")); | 825 | puts(_("r\treturn to main menu")); |
834 | puts(_("\td\tprint the raw data in the partition table")); | 826 | puts(_("s\tchange number of sectors/track")); |
835 | puts(_("\te\tlist extended partitions")); /* !sun */ | 827 | puts(_("v\tverify the partition table")); |
836 | puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */ | 828 | puts(_("w\twrite table to disk and exit")); |
837 | puts(_("\th\tchange number of heads")); | 829 | } else { |
838 | puts(_("\tm\tprint this menu")); | 830 | puts(_("b\tmove beginning of data in a partition")); /* !sun */ |
839 | puts(_("\tp\tprint the partition table")); | 831 | puts(_("c\tchange number of cylinders")); |
840 | puts(_("\tq\tquit without saving changes")); | 832 | puts(_("d\tprint the raw data in the partition table")); |
841 | puts(_("\tr\treturn to main menu")); | 833 | puts(_("e\tlist extended partitions")); /* !sun */ |
842 | puts(_("\ts\tchange number of sectors/track")); | 834 | puts(_("f\tfix partition order")); /* !sun, !aix, !sgi */ |
843 | puts(_("\tv\tverify the partition table")); | ||
844 | puts(_("\tw\twrite table to disk and exit")); | ||
845 | } else { | ||
846 | puts(_("Command action")); | ||
847 | puts(_("\tb\tmove beginning of data in a partition")); /* !sun */ | ||
848 | puts(_("\tc\tchange number of cylinders")); | ||
849 | puts(_("\td\tprint the raw data in the partition table")); | ||
850 | puts(_("\te\tlist extended partitions")); /* !sun */ | ||
851 | puts(_("\tf\tfix partition order")); /* !sun, !aix, !sgi */ | ||
852 | #if ENABLE_FEATURE_SGI_LABEL | 835 | #if ENABLE_FEATURE_SGI_LABEL |
853 | puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */ | 836 | puts(_("g\tcreate an IRIX (SGI) partition table"));/* sgi */ |
854 | #endif | 837 | #endif |
855 | puts(_("\th\tchange number of heads")); | 838 | puts(_("h\tchange number of heads")); |
856 | puts(_("\tm\tprint this menu")); | 839 | puts(_("p\tprint the partition table")); |
857 | puts(_("\tp\tprint the partition table")); | 840 | puts(_("q\tquit without saving changes")); |
858 | puts(_("\tq\tquit without saving changes")); | 841 | puts(_("r\treturn to main menu")); |
859 | puts(_("\tr\treturn to main menu")); | 842 | puts(_("s\tchange number of sectors/track")); |
860 | puts(_("\ts\tchange number of sectors/track")); | 843 | puts(_("v\tverify the partition table")); |
861 | puts(_("\tv\tverify the partition table")); | 844 | puts(_("w\twrite table to disk and exit")); |
862 | puts(_("\tw\twrite table to disk and exit")); | ||
863 | } | 845 | } |
864 | } | 846 | } |
865 | #endif /* ADVANCED mode */ | 847 | #endif /* ADVANCED mode */ |
@@ -883,7 +865,7 @@ static const char *partition_type(unsigned char type) | |||
883 | const struct systypes *types = get_sys_types(); | 865 | const struct systypes *types = get_sys_types(); |
884 | 866 | ||
885 | for (i = 0; types[i].name; i++) | 867 | for (i = 0; types[i].name; i++) |
886 | if ((unsigned char )types[i].name[0] == type) | 868 | if ((unsigned char)types[i].name[0] == type) |
887 | return types[i].name + 1; | 869 | return types[i].name + 1; |
888 | 870 | ||
889 | return _("Unknown"); | 871 | return _("Unknown"); |
@@ -899,24 +881,29 @@ get_sysid(int i) | |||
899 | ptes[i].part_table->sys_ind); | 881 | ptes[i].part_table->sys_ind); |
900 | } | 882 | } |
901 | 883 | ||
902 | void list_types(const struct systypes *sys) | 884 | static void list_types(const struct systypes *sys) |
903 | { | 885 | { |
904 | unsigned last[4], done = 0, next = 0, size; | 886 | enum { COLS = 3 }; |
887 | |||
888 | unsigned last[COLS]; | ||
889 | unsigned done, next, size; | ||
905 | int i; | 890 | int i; |
906 | 891 | ||
907 | for (i = 0; sys[i].name; i++); | 892 | for (size = 0; sys[size].name; size++) /* */; |
908 | size = i; | ||
909 | 893 | ||
910 | for (i = 3; i >= 0; i--) | 894 | done = 0; |
911 | last[3 - i] = done += (size + i - done) / (i + 1); | 895 | for (i = COLS-1; i >= 0; i--) { |
912 | i = done = 0; | 896 | done += (size + i - done) / (i + 1); |
897 | last[COLS-1 - i] = done; | ||
898 | } | ||
913 | 899 | ||
900 | i = done = next = 0; | ||
914 | do { | 901 | do { |
915 | printf("%c%2x %-15.15s", i ? ' ' : '\n', | 902 | printf("%c%2x %-22.22s", i ? ' ' : '\n', |
916 | (unsigned char)sys[next].name[0], | 903 | (unsigned char)sys[next].name[0], |
917 | partition_type((unsigned char)sys[next].name[0])); | 904 | sys[next].name + 1); |
918 | next = last[i++] + done; | 905 | next = last[i++] + done; |
919 | if (i > 3 || next >= last[i]) { | 906 | if (i >= COLS || next >= last[i]) { |
920 | i = 0; | 907 | i = 0; |
921 | next = ++done; | 908 | next = ++done; |
922 | } | 909 | } |
@@ -2415,10 +2402,12 @@ new_partition(void) | |||
2415 | "an extended partition first\n")); | 2402 | "an extended partition first\n")); |
2416 | } else { | 2403 | } else { |
2417 | char c, line[LINE_LENGTH]; | 2404 | char c, line[LINE_LENGTH]; |
2418 | snprintf(line, sizeof(line), "%s\n %s\n p primary " | 2405 | snprintf(line, sizeof(line), |
2419 | "partition (1-4)\n", | 2406 | "Command action\n" |
2420 | "Command action", (extended_offset ? | 2407 | " %s\n" |
2421 | "l logical (5 or over)" : "e extended")); | 2408 | " p primary partition (1-4)\n", |
2409 | (extended_offset ? | ||
2410 | "l logical (5 or over)" : "e extended")); | ||
2422 | while (1) { | 2411 | while (1) { |
2423 | c = read_nonempty(line); | 2412 | c = read_nonempty(line); |
2424 | if (c == 'p' || c == 'P') { | 2413 | if (c == 'p' || c == 'P') { |
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index 16a046ea3..3f56bd27d 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c | |||
@@ -308,22 +308,21 @@ bsd_trydev(const char * dev) | |||
308 | static void | 308 | static void |
309 | bsd_menu(void) | 309 | bsd_menu(void) |
310 | { | 310 | { |
311 | puts(_("Command action")); | 311 | puts(_("Command Action")); |
312 | puts(_("\td\tdelete a BSD partition")); | 312 | puts(_("d\tdelete a BSD partition")); |
313 | puts(_("\te\tedit drive data")); | 313 | puts(_("e\tedit drive data")); |
314 | puts(_("\ti\tinstall bootstrap")); | 314 | puts(_("i\tinstall bootstrap")); |
315 | puts(_("\tl\tlist known filesystem types")); | 315 | puts(_("l\tlist known filesystem types")); |
316 | puts(_("\tm\tprint this menu")); | 316 | puts(_("n\tadd a new BSD partition")); |
317 | puts(_("\tn\tadd a new BSD partition")); | 317 | puts(_("p\tprint BSD partition table")); |
318 | puts(_("\tp\tprint BSD partition table")); | 318 | puts(_("q\tquit without saving changes")); |
319 | puts(_("\tq\tquit without saving changes")); | 319 | puts(_("r\treturn to main menu")); |
320 | puts(_("\tr\treturn to main menu")); | 320 | puts(_("s\tshow complete disklabel")); |
321 | puts(_("\ts\tshow complete disklabel")); | 321 | puts(_("t\tchange a partition's filesystem id")); |
322 | puts(_("\tt\tchange a partition's filesystem id")); | 322 | puts(_("u\tchange units (cylinders/sectors)")); |
323 | puts(_("\tu\tchange units (cylinders/sectors)")); | 323 | puts(_("w\twrite disklabel to disk")); |
324 | puts(_("\tw\twrite disklabel to disk")); | ||
325 | #if !defined(__alpha__) | 324 | #if !defined(__alpha__) |
326 | puts(_("\tx\tlink BSD partition to non-BSD partition")); | 325 | puts(_("x\tlink BSD partition to non-BSD partition")); |
327 | #endif | 326 | #endif |
328 | } | 327 | } |
329 | 328 | ||
@@ -633,13 +632,15 @@ xbsd_create_disklabel(void) | |||
633 | static int | 632 | static int |
634 | edit_int(int def, char *mesg) | 633 | edit_int(int def, char *mesg) |
635 | { | 634 | { |
635 | mesg = xasprintf("%s (%d): ", mesg, def); | ||
636 | do { | 636 | do { |
637 | fputs(mesg, stdout); | 637 | if (!read_line(mesg)) |
638 | printf(" (%d): ", def); | 638 | goto ret; |
639 | if (!read_line()) | ||
640 | return def; | ||
641 | } while (!isdigit(*line_ptr)); | 639 | } while (!isdigit(*line_ptr)); |
642 | return atoi(line_ptr); | 640 | def = atoi(line_ptr); |
641 | ret: | ||
642 | free(mesg); | ||
643 | return def; | ||
643 | } | 644 | } |
644 | 645 | ||
645 | static void | 646 | static void |
@@ -718,10 +719,9 @@ xbsd_write_bootstrap(void) | |||
718 | else | 719 | else |
719 | dkbasename = "wd"; | 720 | dkbasename = "wd"; |
720 | 721 | ||
721 | printf(_("Bootstrap: %sboot -> boot%s (%s): "), | 722 | snprintf(path, sizeof(path), "Bootstrap: %sboot -> boot%s (%s): ", |
722 | dkbasename, dkbasename, dkbasename); | 723 | dkbasename, dkbasename, dkbasename); |
723 | if (read_line()) { | 724 | if (read_line(path)) { |
724 | line_ptr[strlen(line_ptr)-1] = '\0'; | ||
725 | dkbasename = line_ptr; | 725 | dkbasename = line_ptr; |
726 | } | 726 | } |
727 | snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename); | 727 | snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename); |