(make history and completion optional at runtime).
Use it for fdisk, as an example.
Some unrelated fixes in fdisk are also here.
#endif
+#if ENABLE_FEATURE_COMMAND_EDITING
+/* It's NOT just ENABLEd or disabled. It's a number: */
+#ifdef CONFIG_FEATURE_COMMAND_HISTORY
+#define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0)
+#else
+#define MAX_HISTORY 0
+#endif
+struct line_input_t {
+ int flags;
+ const char *path_lookup;
+#if MAX_HISTORY
+ int cnt_history;
+ int cur_history;
+ USE_FEATURE_COMMAND_SAVEHISTORY(const char *hist_file;)
+ char *history[MAX_HISTORY + 1];
+#endif
+};
+enum {
+ DO_HISTORY = 1 * (MAX_HISTORY > 0),
+ SAVE_HISTORY = 2 * (MAX_HISTORY > 0) * ENABLE_FEATURE_COMMAND_SAVEHISTORY,
+ TAB_COMPLETION = 4 * ENABLE_FEATURE_COMMAND_TAB_COMPLETION,
+ USERNAME_COMPLETION = 8 * ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION,
+ VI_MODE = 0x10 * ENABLE_FEATURE_COMMAND_EDITING_VI,
+ WITH_PATH_LOOKUP = 0x20,
+ FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION,
+};
+typedef struct line_input_t line_input_t;
+line_input_t *new_line_input_t(int flags);
+int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state);
+#else
+int read_line_input(const char* prompt, char* command, int maxsize);
+#define read_line_input(prompt, command, maxsize, state) \
+ read_line_input(prompt, command, maxsize)
+#endif
+
+
#ifndef COMM_LEN
#ifdef TASK_COMM_LEN
enum { COMM_LEN = TASK_COMM_LEN };
# Licensed under the GPL v2, see the file LICENSE in this tarball.
lib-y:=
-lib-$(CONFIG_ASH) += ash.o
-lib-$(CONFIG_HUSH) += hush.o
-lib-$(CONFIG_LASH) += lash.o
-lib-$(CONFIG_MSH) += msh.o
-lib-$(CONFIG_FEATURE_COMMAND_EDITING) += cmdedit.o
+lib-y += cmdedit.o
+lib-$(CONFIG_ASH) += ash.o
+lib-$(CONFIG_HUSH) += hush.o
+lib-$(CONFIG_LASH) += lash.o
+lib-$(CONFIG_MSH) += msh.o
#include <termios.h>
#endif
-#include "cmdedit.h"
#ifdef __GLIBC__
/* glibc sucks */
static int getoptscmd(int, char **);
#endif
static int hashcmd(int, char **);
-#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
+#if !ENABLE_FEATURE_SH_EXTRA_QUIET
static int helpcmd(int argc, char **argv);
#endif
#if JOBS
{ BUILTIN_REGULAR "getopts", getoptscmd },
#endif
{ BUILTIN_NOSPEC "hash", hashcmd },
-#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
+#if !ENABLE_FEATURE_SH_EXTRA_QUIET
{ BUILTIN_NOSPEC "help", helpcmd },
#endif
#if JOBS
{0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_ALL\0", change_lc_all },
{0, VSTRFIXED | VTEXTFIXED | VUNSET, "LC_CTYPE\0", change_lc_ctype },
#endif
-#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
+#if ENABLE_FEATURE_COMMAND_SAVEHISTORY
{0, VSTRFIXED | VTEXTFIXED | VUNSET, "HISTFILE\0", NULL },
#endif
};
#define debug optlist[15]
#endif
-#ifndef CONFIG_FEATURE_COMMAND_EDITING_VI
-#define setvimode(on) viflag = 0 /* forcibly keep the option off */
-#endif
-
/* options.c */
clearredir(1);
envp = environment();
if (strchr(argv[0], '/') || is_safe_applet(argv[0])
-#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
+#if ENABLE_FEATURE_SH_STANDALONE_SHELL
|| find_applet_by_name(argv[0])
#endif
) {
applet_name = cmd;
exit(a->main(argc, argv));
}
-#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
+#if ENABLE_FEATURE_SH_STANDALONE_SHELL
if (find_applet_by_name(cmd) != NULL) {
/* re-exec ourselves with the new arguments */
execve(CONFIG_BUSYBOX_EXEC_PATH,argv,envp);
return;
}
-#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
+#if ENABLE_FEATURE_SH_STANDALONE_SHELL
if (find_applet_by_name(name)) {
entry->cmdtype = CMDNORMAL;
entry->u.index = -1;
}
-
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
-#ifdef CONFIG_ASH_EXPAND_PRMT
-static char *cmdedit_prompt;
-#else
+#if ENABLE_FEATURE_COMMAND_EDITING
+static line_input_t *line_input_state;
+//static SKIP_ASH_EXPAND_PRMT(const) char *cmdedit_prompt;
static const char *cmdedit_prompt;
-#endif
static void putprompt(const char *s)
{
-#ifdef CONFIG_ASH_EXPAND_PRMT
- free(cmdedit_prompt);
- cmdedit_prompt = xstrdup(s);
-#else
+ if (ENABLE_ASH_EXPAND_PRMT) {
+ free((char*)cmdedit_prompt);
+ cmdedit_prompt = xstrdup(s);
+ return;
+ }
cmdedit_prompt = s;
-#endif
}
#else
static void putprompt(const char *s)
}
#endif
+#if ENABLE_FEATURE_COMMAND_EDITING_VI
+#define setvimode(on) do { \
+ if (on) line_input_state->flags |= VI_MODE; \
+ else line_input_state->flags &= ~VI_MODE; \
+} while (0)
+#else
+#define setvimode(on) viflag = 0 /* forcibly keep the option off */
+#endif
+
+
static int preadfd(void)
{
int nr;
parsenextc = buf;
retry:
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
if (!iflag || parsefile->fd)
nr = safe_read(parsefile->fd, buf, BUFSIZ - 1);
else {
-#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETION
- cmdedit_path_lookup = pathval();
+#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
+ line_input_state->path_lookup = pathval();
#endif
- nr = cmdedit_read_input((char *) cmdedit_prompt, buf);
- if(nr == 0) {
- /* Ctrl+C presend */
- if(trap[SIGINT]) {
+ nr = read_line_input(cmdedit_prompt, buf, BUFSIZ, line_input_state);
+ if (nr == 0) {
+ /* Ctrl+C pressed */
+ if (trap[SIGINT]) {
buf[0] = '\n';
- buf[1] = 0;
+ buf[1] = '\0';
raise(SIGINT);
return 1;
}
goto retry;
}
- if(nr < 0 && errno == 0) {
+ if (nr < 0 && errno == 0) {
/* Ctrl+D presend */
nr = 0;
}
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
+
+#if ENABLE_FEATURE_COMMAND_EDITING
+ line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
+#endif
state = 0;
if (setjmp(jmploc.loc)) {
int e;
init();
setstackmark(&smark);
procargs(argc, argv);
-#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
- if ( iflag ) {
+#if ENABLE_FEATURE_COMMAND_SAVEHISTORY
+ if (iflag) {
const char *hp = lookupvar("HISTFILE");
- if(hp == NULL ) {
+ if (hp == NULL) {
hp = lookupvar("HOME");
if(hp != NULL) {
char *defhp = concat_path_file(hp, ".ash_history");
evalstring(minusc, 0);
if (sflag || minusc == NULL) {
-#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
- if ( iflag ) {
- const char *hp = lookupvar("HISTFILE");
+#if ENABLE_FEATURE_COMMAND_SAVEHISTORY
+ if ( iflag ) {
+ const char *hp = lookupvar("HISTFILE");
- if(hp != NULL )
- load_history ( hp );
- }
+ if (hp != NULL)
+ line_input_state->hist_file = hp;
+ }
#endif
-state4: /* XXX ??? - why isn't this before the "if" statement */
+ state4: /* XXX ??? - why isn't this before the "if" statement */
cmdloop(1);
}
#if PROFILE
setsignal(SIGINT);
setsignal(SIGQUIT);
setsignal(SIGTERM);
-#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
+#if !ENABLE_FEATURE_SH_EXTRA_QUIET
if(is_interactive > 1) {
/* Looks like they want an interactive shell */
static int do_banner;
}
-#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
+#if !ENABLE_FEATURE_SH_EXTRA_QUIET
/*** List the available builtins ***/
static int helpcmd(int argc, char **argv)
col = 0;
}
}
-#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
+#if ENABLE_FEATURE_SH_STANDALONE_SHELL
for (i = 0; i < NUM_APPLETS; i++) {
col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name);
if (col > 60) {
/* dash bug: it just does _exit(exitstatus) here
* but we have to do setjobctl(0) first!
* (bug is still not fixed in dash-0.5.3 - if you run dash
- * under Midnight Commander, on exit MC is backgrounded) */
+ * under Midnight Commander, on exit from dash MC is backgrounded) */
status = exitstatus;
goto out;
}
evalstring(p, 0);
}
flushall();
-#ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY
- if (iflag && rootshell) {
- const char *hp = lookupvar("HISTFILE");
-
- if (hp != NULL)
- save_history(hp);
- }
-#endif
out:
setjobctl(0);
_exit(status);
#define endexpression &op_tokens[sizeof(op_tokens)-7]
-static arith_t arith (const char *expr, int *perrcode)
+static arith_t arith(const char *expr, int *perrcode)
{
char arithval; /* Current character under analysis */
operator lasttok, op;
#include <sys/ioctl.h>
#include "busybox.h"
-#include "cmdedit.h"
/* FIXME: obsolete CONFIG item? */
/* Entire file (except TESTing part) sits inside this #if */
#if ENABLE_FEATURE_COMMAND_EDITING
-
#if ENABLE_LOCALE_SUPPORT
#define Isprint(c) isprint(c)
#else
#define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \
(ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION || ENABLE_FEATURE_SH_FANCY_PROMPT)
-/* Maximum length of command line history */
-#if !ENABLE_FEATURE_COMMAND_HISTORY
-#define MAX_HISTORY 15
-#else
-#define MAX_HISTORY (CONFIG_FEATURE_COMMAND_HISTORY + 0)
-#endif
+static line_input_t *state;
-/* Current termios and the previous termios before starting sh */
static struct termios initial_settings, new_settings;
-static
-volatile unsigned cmdedit_termw = 80; /* actual terminal width */
-
+static volatile unsigned cmdedit_termw = 80; /* actual terminal width */
static int cmdedit_x; /* real x terminal position */
static int cmdedit_y; /* pseudoreal y terminal position */
static int cmdedit_prmt_len; /* length of prompt (without colors etc) */
-static int cursor;
-static int len;
+static unsigned cursor;
+static unsigned command_len;
static char *command_ps;
-static SKIP_FEATURE_SH_FANCY_PROMPT(const) char *cmdedit_prompt;
+static const char *cmdedit_prompt;
#if ENABLE_FEATURE_SH_FANCY_PROMPT
static char *hostname_buf;
/* Move to end of line (by printing all chars till the end) */
static void input_end(void)
{
- while (cursor < len)
+ while (cursor < command_len)
cmdedit_set_out_char(' ');
}
static void put_prompt(void)
{
out1str(cmdedit_prompt);
- cmdedit_x = cmdedit_prmt_len; /* count real x terminal position */
+ cmdedit_x = cmdedit_prmt_len;
cursor = 0;
// Huh? what if cmdedit_prmt_len >= width?
cmdedit_y = 0; /* new quasireal y */
{
int j = cursor;
- if (j == len)
+ if (j == command_len)
return;
#if ENABLE_FEATURE_COMMAND_EDITING_VI
#endif
strcpy(command_ps + j, command_ps + j + 1);
- len--;
+ command_len--;
input_end(); /* rewrite new line */
cmdedit_set_out_char(' '); /* erase char */
input_backward(cursor - j); /* back to old pos cursor */
/* Move forward one character */
static void input_forward(void)
{
- if (cursor < len)
+ if (cursor < command_len)
cmdedit_set_out_char(command_ps[cursor + 1]);
}
FIND_FILE_ONLY = 2,
};
-#if ENABLE_ASH
-const char *cmdedit_path_lookup;
-#endif
static int path_parse(char ***p, int flags)
{
int npth;
const char *tmp;
-#if ENABLE_ASH
- const char *pth = cmdedit_path_lookup;
-#else
- const char *pth = getenv("PATH")
-#endif
+ const char *pth;
+ char **res;
/* if not setenv PATH variable, to search cur dir "." */
if (flags != FIND_EXE_ONLY)
return 1;
+
+ if (state->flags & WITH_PATH_LOOKUP)
+ pth = state->path_lookup;
+ else
+ pth = getenv("PATH");
/* PATH=<empty> or PATH=:<empty> */
if (!pth || !pth[0] || LONE_CHAR(pth, ':'))
return 1;
tmp = pth;
- npth = 0;
-
+ npth = 1; /* path component count */
while (1) {
- npth++; /* count words is + 1 count ':' */
tmp = strchr(tmp, ':');
if (!tmp)
break;
if (*++tmp == '\0')
break; /* :<empty> */
+ npth++;
}
- *p = xmalloc(npth * sizeof(char *));
-
+ res = xmalloc(npth * sizeof(char*));
+ res[0] = xstrdup(pth);
tmp = pth;
- (*p)[0] = xstrdup(tmp);
- npth = 1; /* count words is + 1 count ':' */
-
+ npth = 1;
while (1) {
tmp = strchr(tmp, ':');
if (!tmp)
break;
- (*p)[0][(tmp - pth)] = 0; /* ':' -> '\0' */
- if (*++tmp == 0)
- break; /* :<empty> */
- (*p)[npth++] = &(*p)[0][(tmp - pth)]; /* p[next]=p[0][&'\0'+1] */
+ *tmp++ = '\0'; /* ':' -> '\0' */
+ if (*tmp == '\0')
+ break; /* :<empty> */
+ res[npth++] = tmp;
}
-
+ *p = res;
return npth;
}
/* Do TAB completion */
static void input_tab(int *lastWasTab)
{
+ if (!(state->flags & TAB_COMPLETION))
+ return;
+
if (!*lastWasTab) {
char *tmp, *tmp1;
int len_found;
#if ENABLE_FEATURE_COMMAND_USERNAME_COMPLETION
/* If the word starts with `~' and there is no slash in the word,
* then try completing this word as a username. */
-
- if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0)
- username_tab_completion(matchBuf, NULL);
- if (!matches)
+ if (state->flags & USERNAME_COMPLETION)
+ if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0)
+ username_tab_completion(matchBuf, NULL);
#endif
/* Try to match any executable in our path and everything
* in the current working directory */
+ if (!matches)
exe_n_cwd_tab_completion(matchBuf, find_type);
/* Sort, then remove any duplicates found */
if (matches) {
}
}
+#else
+#define input_tab(a) ((void)0)
#endif /* FEATURE_COMMAND_TAB_COMPLETION */
#if MAX_HISTORY > 0
-static char *history[MAX_HISTORY+1]; /* history + current */
-/* saved history lines */
-static int n_history;
-/* current pointer to history line */
-static int cur_history;
-
+/* state->flags is already checked to be nonzero */
static void get_previous_history(void)
{
- if (command_ps[0] != '\0' || history[cur_history] == NULL) {
- free(history[cur_history]);
- history[cur_history] = xstrdup(command_ps);
+ if (command_ps[0] != '\0' || state->history[state->cur_history] == NULL) {
+ free(state->history[state->cur_history]);
+ state->history[state->cur_history] = xstrdup(command_ps);
}
- cur_history--;
+ state->cur_history--;
}
static int get_next_history(void)
{
- int ch = cur_history;
-
- if (ch < n_history) {
- get_previous_history(); /* save the current history line */
- cur_history = ch + 1;
- return cur_history;
- } else {
- beep();
- return 0;
+ if (state->flags & DO_HISTORY) {
+ int ch = state->cur_history;
+ if (ch < state->cnt_history) {
+ get_previous_history(); /* save the current history line */
+ state->cur_history = ch + 1;
+ return state->cur_history;
+ }
}
+ beep();
+ return 0;
}
#if ENABLE_FEATURE_COMMAND_SAVEHISTORY
+/* state->flags is already checked to be nonzero */
void load_history(const char *fromfile)
{
FILE *fp;
int hi;
/* cleanup old */
-
- for (hi = n_history; hi > 0;) {
+ for (hi = state->cnt_history; hi > 0;) {
hi--;
- free(history[hi]);
+ free(state->history[hi]);
}
fp = fopen(fromfile, "r");
free(hl);
continue;
}
- history[hi++] = hl;
+ state->history[hi++] = hl;
}
fclose(fp);
}
- cur_history = n_history = hi;
+ state->cur_history = state->cnt_history = hi;
}
+/* state->flags is already checked to be nonzero */
void save_history(const char *tofile)
{
- FILE *fp = fopen(tofile, "w");
+ FILE *fp;
+ fp = fopen(tofile, "w");
if (fp) {
int i;
- for (i = 0; i < n_history; i++) {
- fprintf(fp, "%s\n", history[i]);
+ for (i = 0; i < state->cnt_history; i++) {
+ fprintf(fp, "%s\n", state->history[i]);
}
fclose(fp);
}
}
+#else
+#define load_history(a) ((void)0)
+#define save_history(a) ((void)0)
#endif /* FEATURE_COMMAND_SAVEHISTORY */
-#endif /* MAX_HISTORY > 0 */
+static void remember_in_history(const char *str)
+{
+ int i;
+
+ if (!(state->flags & DO_HISTORY))
+ return;
+
+ i = state->cnt_history;
+ free(state->history[MAX_HISTORY]);
+ state->history[MAX_HISTORY] = NULL;
+ /* After max history, remove the oldest command */
+ if (i >= MAX_HISTORY) {
+ free(state->history[0]);
+ for (i = 0; i < MAX_HISTORY-1; i++)
+ state->history[i] = state->history[i+1];
+ }
+// Maybe "if (!i || strcmp(history[i-1], command) != 0) ..."
+// (i.e. do not save dups?)
+ state->history[i++] = xstrdup(str);
+ state->cur_history = i;
+ state->cnt_history = i;
+ if (state->flags & SAVE_HISTORY)
+ save_history(state->hist_file);
+ USE_FEATURE_SH_FANCY_PROMPT(num_ok_lines++;)
+}
+
+#else /* MAX_HISTORY == 0 */
+#define remember_in_history(a) ((void)0)
+#endif /* MAX_HISTORY */
/*
*/
#if ENABLE_FEATURE_COMMAND_EDITING_VI
-static int vi_mode;
-
-void setvimode(int viflag)
-{
- vi_mode = viflag;
-}
-
static void
vi_Word_motion(char *command, int eat)
{
input_backward(1);
}
}
-#else
-enum { vi_mode = 0 };
#endif
/*
- * cmdedit_read_input and its helpers
+ * read_line_input and its helpers
*/
#if !ENABLE_FEATURE_SH_FANCY_PROMPT
cmdedit_prmt_len += cur_prmt_len;
prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
}
- if (pwd_buf!=(char *)bb_msg_unknown)
+ if (pwd_buf != (char *)bb_msg_unknown)
free(pwd_buf);
cmdedit_prompt = prmt_mem_ptr;
put_prompt();
/* new y for current cursor */
int new_y = (cursor + cmdedit_prmt_len) / w;
/* redraw */
- redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), len - cursor);
+ redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), command_len - cursor);
fflush(stdout);
}
}
#undef CTRL
#define CTRL(a) ((a) & ~0x40)
-
-int cmdedit_read_input(char *prompt, char command[BUFSIZ])
+int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *st)
{
+ static const int null_flags;
+
int lastWasTab = FALSE;
unsigned int ic;
unsigned char c;
smallint vi_cmdmode = 0;
smalluint prevc;
#endif
+
+// FIXME: audit & improve this
+ if (maxsize > BUFSIZ)
+ maxsize = BUFSIZ;
+
+ /* With null flags, no other fields are ever used */
+ state = st ? st : (line_input_t*) &null_flags;
+ if (state->flags & SAVE_HISTORY)
+ load_history(state->hist_file);
+
/* prepare before init handlers */
cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */
- len = 0;
+ command_len = 0;
command_ps = command;
command[0] = '\0';
getTermSettings(0, (void *) &initial_settings);
- memcpy(&new_settings, &initial_settings, sizeof(struct termios));
+ memcpy(&new_settings, &initial_settings, sizeof(new_settings));
new_settings.c_lflag &= ~ICANON; /* unbuffered input */
/* Turn off echoing and CTRL-C, so we can trap it */
new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG);
- /* Hmm, in linux c_cc[] not parsed if set ~ICANON */
+ /* Hmm, in linux c_cc[] is not parsed if ICANON is off */
new_settings.c_cc[VMIN] = 1;
new_settings.c_cc[VTIME] = 0;
/* Turn off CTRL-C, so we can trap it */
vi_case(CTRL('C')|vbit:)
/* Control-c -- stop gathering input */
goto_new_line();
-#if !ENABLE_ASH
- command[0] = '\0';
- len = 0;
- lastWasTab = FALSE;
- put_prompt();
-#else
- len = 0;
- break_out = -1; /* to control traps */
-#endif
+ command_len = 0;
+ break_out = -1; /* "do not append '\n'" */
break;
case CTRL('D'):
/* Control-d -- Delete one character, or exit
* if the len=0 and no chars to delete */
- if (len == 0) {
+ if (command_len == 0) {
errno = 0;
prepare_to_die:
-// So, our API depends on whether we have ash compiled in or not? Crap...
-#if !ENABLE_ASH
- printf("exit");
- goto_new_line();
- /* cmdedit_reset_term() called in atexit */
-// FIXME. this is definitely not good
- exit(EXIT_SUCCESS);
-#else
/* to control stopped jobs */
- break_out = len = -1;
+ break_out = command_len = -1;
break;
-#endif
}
input_delete(0);
break;
break;
case '\t':
-#if ENABLE_FEATURE_COMMAND_TAB_COMPLETION
input_tab(&lastWasTab);
-#endif
break;
#if ENABLE_FEATURE_EDITING_FANCY_KEYS
case CTRL('K'):
/* Control-k -- clear to end of line */
command[cursor] = 0;
- len = cursor;
+ command_len = cursor;
printf("\033[J");
break;
case CTRL('L'):
vi_case(CTRL('L')|vbit:)
/* Control-l -- clear screen */
printf("\033[H");
- redraw(0, len - cursor);
+ redraw(0, command_len - cursor);
break;
#endif
vi_case(CTRL('P')|vbit:)
vi_case('k'|vbit:)
/* Control-p -- Get previous command from history */
- if (cur_history > 0) {
+ if ((state->flags & DO_HISTORY) && state->cur_history > 0) {
get_previous_history();
goto rewrite_line;
- } else {
- beep();
}
+ beep();
break;
#endif
/* Control-U -- Clear line before cursor */
if (cursor) {
strcpy(command, command + cursor);
- redraw(cmdedit_y, len -= cursor);
+ command_len -= cursor;
+ redraw(cmdedit_y, command_len);
}
break;
#endif
break;
case '$': /* "d$", "c$" */
clear_to_eol:
- while (cursor < len)
+ while (cursor < command_len)
input_delete(1);
break;
}
case '\x1b': /* ESC */
#if ENABLE_FEATURE_COMMAND_EDITING_VI
- if (vi_mode) {
+ if (state->flags & VI_MODE) {
/* ESC: insert mode --> command mode */
vi_cmdmode = 1;
input_backward(1);
#if MAX_HISTORY > 0
case 'A':
/* Up Arrow -- Get previous command from history */
- if (cur_history > 0) {
+ if ((state->flags & DO_HISTORY) && state->cur_history > 0) {
get_previous_history();
goto rewrite_line;
}
rewrite_line:
/* Rewrite the line with the selected history item */
/* change command */
- len = strlen(strcpy(command, history[cur_history]));
+ command_len = strlen(strcpy(command, state->history[state->cur_history]));
/* redraw and go to eol (bol, in vi */
- redraw(cmdedit_y, vi_mode ? 9999 : 0);
+ redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0);
break;
#endif
case 'C':
if (!Isprint(c)) /* Skip non-printable characters */
break;
- if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */
+ if (command_len >= (maxsize - 2)) /* Need to leave space for enter */
break;
- len++;
- if (cursor == (len - 1)) { /* Append if at the end of the line */
+ command_len++;
+ if (cursor == (command_len - 1)) { /* Append if at the end of the line */
command[cursor] = c;
command[cursor+1] = '\0';
cmdedit_set_out_char(' ');
} else { /* Insert otherwise */
int sc = cursor;
- memmove(command + sc + 1, command + sc, len - sc);
+ memmove(command + sc + 1, command + sc, command_len - sc);
command[sc] = c;
sc++;
/* rewrite from cursor */
lastWasTab = FALSE;
}
-#if MAX_HISTORY > 0
- /* Handle command history log */
- /* cleanup may be saved current command line */
- if (len > 0) {
- int i = n_history;
-
- free(history[MAX_HISTORY]);
- history[MAX_HISTORY] = NULL;
- /* After max history, remove the oldest command */
- if (i >= MAX_HISTORY) {
- free(history[0]);
- for (i = 0; i < MAX_HISTORY-1; i++)
- history[i] = history[i+1];
- }
-// Maybe "if (!i || strcmp(history[i-1], command) != 0) ..."
-// (i.e. do not save dups?)
- history[i++] = xstrdup(command);
- cur_history = i;
- n_history = i;
- USE_FEATURE_SH_FANCY_PROMPT(num_ok_lines++;)
- }
-#else /* MAX_HISTORY == 0 */
- /* dont put empty line */
- USE_FEATURE_SH_FANCY_PROMPT(if (len > 0) num_ok_lines++;)
-#endif /* MAX_HISTORY */
+ if (command_len > 0)
+ remember_in_history(command);
if (break_out > 0) {
- command[len++] = '\n';
- command[len] = '\0';
+ command[command_len++] = '\n';
+ command[command_len] = '\0';
}
#if ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_COMMAND_TAB_COMPLETION
#endif
#if ENABLE_FEATURE_SH_FANCY_PROMPT
- free(cmdedit_prompt);
+ free((char*)cmdedit_prompt);
#endif
/* restore initial_settings and SIGWINCH handler */
cmdedit_reset_term();
- return len;
+ return command_len;
+}
+
+line_input_t *new_line_input_t(int flags)
+{
+ line_input_t *n = xzalloc(sizeof(*n));
+ n->flags = flags;
+ return n;
+}
+
+#else
+
+#undef read_line_input
+int read_line_input(const char* prompt, char* command, int maxsize)
+{
+ fputs(prompt, stdout);
+ fflush(stdout);
+ fgets(command, maxsize, stdin);
+ return strlen(command);
}
#endif /* FEATURE_COMMAND_EDITING */
#endif
while (1) {
int l;
- l = cmdedit_read_input(prompt, buff);
+ l = read_line_input(prompt, buff);
if (l <= 0 || buff[l-1] != '\n')
break;
buff[l-1] = 0;
- printf("*** cmdedit_read_input() returned line =%s=\n", buff);
+ printf("*** read_line_input() returned line =%s=\n", buff);
}
- printf("*** cmdedit_read_input() detect ^D\n");
+ printf("*** read_line_input() detect ^D\n");
return 0;
}
-/* vi: set sw=4 ts=4: */
-#ifndef CMDEDIT_H
-#define CMDEDIT_H
-
-int cmdedit_read_input(char* promptStr, char* command);
-
-#if ENABLE_ASH
-extern const char *cmdedit_path_lookup;
-#endif
-
-#if ENABLE_FEATURE_COMMAND_SAVEHISTORY
-void load_history(const char *fromfile);
-void save_history(const char *tofile);
-#endif
-
-#if ENABLE_FEATURE_COMMAND_EDITING_VI
-void setvimode(int viflag);
-#endif
-
-#endif /* CMDEDIT_H */
+/* TO DELETE */
/* #include <dmalloc.h> */
/* #define DEBUG_SHELL */
-#include "cmdedit.h"
#define SPECIAL_VAR_SYMBOL 03
#define FLAG_EXIT_FROM_LOOP 1
debug_printf("result %s\n",*prompt_str);
}
+#if ENABLE_FEATURE_COMMAND_EDITING
+static line_input_t *line_input_state;
+#endif
+
static void get_user_input(struct in_str *i)
{
char *prompt_str;
static char the_command[BUFSIZ];
setup_prompt_string(i->promptmode, &prompt_str);
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
/*
** enable command line editing only while a command line
** is actually being read; otherwise, we'll end up bequeathing
** atexit() handlers and other unwanted stuff to our
** child processes (rob@sysgo.de)
*/
- cmdedit_read_input(prompt_str, the_command);
+ read_line_input(prompt_str, the_command, BUFSIZ, line_input_state);
#else
fputs(prompt_str, stdout);
fflush(stdout);
FILE *input;
char **e = environ;
+#ifdef CONFIG_FEATURE_COMMAND_EDITING
+ line_input_state = new_line_input_t(FOR_SHELL);
+#endif
+
/* XXX what should these be while sourcing /etc/profile? */
global_argc = argc;
global_argv = argv;
#include "busybox.h"
#include <getopt.h>
-#include "cmdedit.h"
-
#include <glob.h>
#define expand_t glob_t
#endif
}
+#if ENABLE_FEATURE_COMMAND_EDITING
+static line_input_t *line_input_state;
+#endif
+
static int get_command(FILE * source, char *command)
{
char *prompt_str;
if (source == stdin) {
setup_prompt_string(&prompt_str);
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
/*
** enable command line editing only while a command line
** is actually being read; otherwise, we'll end up bequeathing
** atexit() handlers and other unwanted stuff to our
** child processes (rob@sysgo.de)
*/
- cmdedit_read_input(prompt_str, command);
+ read_line_input(prompt_str, command, BUFSIZ, line_input_state);
return 0;
#else
fputs(prompt_str, stdout);
argc = argc_l;
argv = argv_l;
+#if ENABLE_FEATURE_COMMAND_EDITING
+ line_input_state = new_line_input_t(FOR_SHELL);
+#endif
+
/* These variables need re-initializing when recursing */
last_jobid = 0;
close_me_list = NULL;
#include <setjmp.h>
#include <sys/times.h>
-#include "cmdedit.h"
/*#define MSHDEBUG 1*/
#endif /* MSHDEBUG */
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
static char *current_prompt;
#endif
*/
+#if ENABLE_FEATURE_COMMAND_EDITING
+static line_input_t *line_input_state;
+#endif
+
int msh_main(int argc, char **argv)
{
int f;
char *name, **ap;
int (*iof) (struct ioarg *);
+#if ENABLE_FEATURE_COMMAND_EDITING
+ line_input_state = new_line_input_t(FOR_SHELL);
+#endif
+
DBGPRINTF(("MSH_MAIN: argc %d, environ %p\n", argc, environ));
initarea();
for (;;) {
if (interactive && e.iop <= iostack) {
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
current_prompt = prompt->value;
#else
prs(prompt->value);
startl = 1;
if (multiline || cf & CONTIN) {
if (interactive && e.iop <= iostack) {
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
current_prompt = cprompt->value;
#else
prs(cprompt->value);
return YYERRCODE;
}
if (interactive && c == '\n' && e.iop <= iostack) {
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
current_prompt = cprompt->value;
#else
prs(cprompt->value);
return e.iop->prev = 0;
}
if (interactive && e.iop == iostack + 1) {
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
current_prompt = prompt->value;
#else
prs(prompt->value);
ap->afpos++;
return *bp->bufp++ & 0177;
}
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
if (interactive && isatty(ap->afile)) {
static char mycommand[BUFSIZ];
static int position = 0, size = 0;
while (size == 0 || position >= size) {
- cmdedit_read_input(current_prompt, mycommand);
+ read_line_input(current_prompt, mycommand, BUFSIZ, line_input_state);
size = strlen(mycommand);
position = 0;
}
return c;
} else
#endif
-
{
i = safe_read(ap->afile, &c, sizeof(c));
return i == sizeof(c) ? (c & 0x7f) : (closef(ap->afile), 0);
e.iobase = e.iop;
for (;;) {
if (interactive && e.iop <= iostack) {
-#ifdef CONFIG_FEATURE_COMMAND_EDITING
+#if ENABLE_FEATURE_COMMAND_EDITING
current_prompt = cprompt->value;
#else
prs(cprompt->value);
})
-#define LINE_LENGTH 800
+#define LINE_LENGTH 80
#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
(n) * sizeof(struct partition)))
#define sector(s) ((s) & 0x3f)
static char line_buffer[LINE_LENGTH];
static char *line_ptr;
-/* read line; return 0 or first char */
+/* read line; return 0 or first printable char */
static int
-read_line(void)
+read_line(const char *prompt)
{
- fflush(stdout); /* requested by niles@scyld.com */
+ int sz;
+
+ sz = read_line_input(prompt, line_buffer, LINE_LENGTH, NULL);
+ if (sz <= 0)
+ exit(0); /* Ctrl-D or Ctrl-C */
+
+ if (line_buffer[sz-1] == '\n')
+ line_buffer[--sz] = '\0';
+
line_ptr = line_buffer;
- if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
- /* error or eof */
- bb_error_msg_and_die("\ngot EOF, exiting");
- }
while (*line_ptr && !isgraph(*line_ptr))
line_ptr++;
return *line_ptr;
static char
read_nonempty(const char *mesg)
{
- do {
- fputs(mesg, stdout);
- } while (!read_line());
+ while (!read_line(mesg)) /* repeat */;
return *line_ptr;
}
static char
read_maybe_empty(const char *mesg)
{
- fputs(mesg, stdout);
- if (!read_line()) {
+ if (!read_line(mesg)) {
line_ptr = line_buffer;
- *line_ptr = '\n';
- line_ptr[1] = 0;
+ line_ptr[0] = '\n';
+ line_ptr[1] = '\0';
}
- return *line_ptr;
+ return line_ptr[0];
}
static int
{ "\x16" "Hidden FAT16" },
{ "\x17" "Hidden HPFS/NTFS" },
{ "\x1b" "Hidden Win95 FAT32" },
- { "\x1c" "Hidden Win95 FAT32 (LBA)" },
- { "\x1e" "Hidden Win95 FAT16 (LBA)" },
- { "\x3c" "PartitionMagic recovery" },
+ { "\x1c" "Hidden W95 FAT32 (LBA)" },
+ { "\x1e" "Hidden W95 FAT16 (LBA)" },
+ { "\x3c" "Part.Magic recovery" },
{ "\x41" "PPC PReP Boot" },
{ "\x42" "SFS" },
{ "\x63" "GNU HURD or SysV" }, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
{ "\x87" "NTFS volume set" },
{ "\x8e" "Linux LVM" },
{ "\x9f" "BSD/OS" }, /* BSDI */
- { "\xa0" "IBM Thinkpad hibernation" },
+ { "\xa0" "Thinkpad hibernation" },
{ "\xa5" "FreeBSD" }, /* various BSD flavours */
{ "\xa6" "OpenBSD" },
{ "\xa8" "Darwin UFS" },
static void
menu(void)
{
+ puts(_("Command Action"));
if (LABEL_IS_SUN) {
- puts(_("Command action"));
- puts(_("\ta\ttoggle a read only flag")); /* sun */
- puts(_("\tb\tedit bsd disklabel"));
- puts(_("\tc\ttoggle the mountable flag")); /* sun */
- puts(_("\td\tdelete a partition"));
- puts(_("\tl\tlist known partition types"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tn\tadd a new partition"));
- puts(_("\to\tcreate a new empty DOS partition table"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */
- puts(_("\tt\tchange a partition's system id"));
- puts(_("\tu\tchange display/entry units"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
+ puts(_("a\ttoggle a read only flag")); /* sun */
+ puts(_("b\tedit bsd disklabel"));
+ puts(_("c\ttoggle the mountable flag")); /* sun */
+ puts(_("d\tdelete a partition"));
+ puts(_("l\tlist known partition types"));
+ puts(_("n\tadd a new partition"));
+ puts(_("o\tcreate a new empty DOS partition table"));
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("s\tcreate a new empty Sun disklabel")); /* sun */
+ puts(_("t\tchange a partition's system id"));
+ puts(_("u\tchange display/entry units"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
#if ENABLE_FEATURE_FDISK_ADVANCED
- puts(_("\tx\textra functionality (experts only)"));
+ puts(_("x\textra functionality (experts only)"));
#endif
- } else
- if (LABEL_IS_SGI) {
- puts(_("Command action"));
- puts(_("\ta\tselect bootable partition")); /* sgi flavour */
- puts(_("\tb\tedit bootfile entry")); /* sgi */
- puts(_("\tc\tselect sgi swap partition")); /* sgi flavour */
- puts(_("\td\tdelete a partition"));
- puts(_("\tl\tlist known partition types"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tn\tadd a new partition"));
- puts(_("\to\tcreate a new empty DOS partition table"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */
- puts(_("\tt\tchange a partition's system id"));
- puts(_("\tu\tchange display/entry units"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
- } else
- if (LABEL_IS_AIX) {
- puts(_("Command action"));
- puts(_("\tm\tprint this menu"));
- puts(_("\to\tcreate a new empty DOS partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */
- } else
- {
- puts(_("Command action"));
- puts(_("\ta\ttoggle a bootable flag"));
- puts(_("\tb\tedit bsd disklabel"));
- puts(_("\tc\ttoggle the dos compatibility flag"));
- puts(_("\td\tdelete a partition"));
- puts(_("\tl\tlist known partition types"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tn\tadd a new partition"));
- puts(_("\to\tcreate a new empty DOS partition table"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\ts\tcreate a new empty Sun disklabel")); /* sun */
- puts(_("\tt\tchange a partition's system id"));
- puts(_("\tu\tchange display/entry units"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
+ } else if (LABEL_IS_SGI) {
+ puts(_("a\tselect bootable partition")); /* sgi flavour */
+ puts(_("b\tedit bootfile entry")); /* sgi */
+ puts(_("c\tselect sgi swap partition")); /* sgi flavour */
+ puts(_("d\tdelete a partition"));
+ puts(_("l\tlist known partition types"));
+ puts(_("n\tadd a new partition"));
+ puts(_("o\tcreate a new empty DOS partition table"));
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("s\tcreate a new empty Sun disklabel")); /* sun */
+ puts(_("t\tchange a partition's system id"));
+ puts(_("u\tchange display/entry units"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
+ } else if (LABEL_IS_AIX) {
+ puts(_("o\tcreate a new empty DOS partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("s\tcreate a new empty Sun disklabel")); /* sun */
+ } else {
+ puts(_("a\ttoggle a bootable flag"));
+ puts(_("b\tedit bsd disklabel"));
+ puts(_("c\ttoggle the dos compatibility flag"));
+ puts(_("d\tdelete a partition"));
+ puts(_("l\tlist known partition types"));
+ puts(_("n\tadd a new partition"));
+ puts(_("o\tcreate a new empty DOS partition table"));
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("s\tcreate a new empty Sun disklabel")); /* sun */
+ puts(_("t\tchange a partition's system id"));
+ puts(_("u\tchange display/entry units"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
#if ENABLE_FEATURE_FDISK_ADVANCED
- puts(_("\tx\textra functionality (experts only)"));
+ puts(_("x\textra functionality (experts only)"));
#endif
}
}
static void
xmenu(void)
{
+ puts(_("Command Action"));
if (LABEL_IS_SUN) {
- puts(_("Command action"));
- puts(_("\ta\tchange number of alternate cylinders")); /*sun*/
- puts(_("\tc\tchange number of cylinders"));
- puts(_("\td\tprint the raw data in the partition table"));
- puts(_("\te\tchange number of extra sectors per cylinder"));/*sun*/
- puts(_("\th\tchange number of heads"));
- puts(_("\ti\tchange interleave factor")); /*sun*/
- puts(_("\to\tchange rotation speed (rpm)")); /*sun*/
- puts(_("\tm\tprint this menu"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\tr\treturn to main menu"));
- puts(_("\ts\tchange number of sectors/track"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
- puts(_("\ty\tchange number of physical cylinders")); /*sun*/
- } else
- if (LABEL_IS_SGI) {
- puts(_("Command action"));
- puts(_("\tb\tmove beginning of data in a partition")); /* !sun */
- puts(_("\tc\tchange number of cylinders"));
- puts(_("\td\tprint the raw data in the partition table"));
- puts(_("\te\tlist extended partitions")); /* !sun */
- puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */
- puts(_("\th\tchange number of heads"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\tr\treturn to main menu"));
- puts(_("\ts\tchange number of sectors/track"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
- } else
- if (LABEL_IS_AIX) {
- puts(_("Command action"));
- puts(_("\tb\tmove beginning of data in a partition")); /* !sun */
- puts(_("\tc\tchange number of cylinders"));
- puts(_("\td\tprint the raw data in the partition table"));
- puts(_("\te\tlist extended partitions")); /* !sun */
- puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */
- puts(_("\th\tchange number of heads"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\tr\treturn to main menu"));
- puts(_("\ts\tchange number of sectors/track"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
- } else {
- puts(_("Command action"));
- puts(_("\tb\tmove beginning of data in a partition")); /* !sun */
- puts(_("\tc\tchange number of cylinders"));
- puts(_("\td\tprint the raw data in the partition table"));
- puts(_("\te\tlist extended partitions")); /* !sun */
- puts(_("\tf\tfix partition order")); /* !sun, !aix, !sgi */
+ puts(_("a\tchange number of alternate cylinders")); /*sun*/
+ puts(_("c\tchange number of cylinders"));
+ puts(_("d\tprint the raw data in the partition table"));
+ puts(_("e\tchange number of extra sectors per cylinder"));/*sun*/
+ puts(_("h\tchange number of heads"));
+ puts(_("i\tchange interleave factor")); /*sun*/
+ puts(_("o\tchange rotation speed (rpm)")); /*sun*/
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("r\treturn to main menu"));
+ puts(_("s\tchange number of sectors/track"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
+ puts(_("y\tchange number of physical cylinders")); /*sun*/
+ } else if (LABEL_IS_SGI) {
+ puts(_("b\tmove beginning of data in a partition")); /* !sun */
+ puts(_("c\tchange number of cylinders"));
+ puts(_("d\tprint the raw data in the partition table"));
+ puts(_("e\tlist extended partitions")); /* !sun */
+ puts(_("g\tcreate an IRIX (SGI) partition table"));/* sgi */
+ puts(_("h\tchange number of heads"));
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("r\treturn to main menu"));
+ puts(_("s\tchange number of sectors/track"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
+ } else if (LABEL_IS_AIX) {
+ puts(_("b\tmove beginning of data in a partition")); /* !sun */
+ puts(_("c\tchange number of cylinders"));
+ puts(_("d\tprint the raw data in the partition table"));
+ puts(_("e\tlist extended partitions")); /* !sun */
+ puts(_("g\tcreate an IRIX (SGI) partition table"));/* sgi */
+ puts(_("h\tchange number of heads"));
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("r\treturn to main menu"));
+ puts(_("s\tchange number of sectors/track"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
+ } else {
+ puts(_("b\tmove beginning of data in a partition")); /* !sun */
+ puts(_("c\tchange number of cylinders"));
+ puts(_("d\tprint the raw data in the partition table"));
+ puts(_("e\tlist extended partitions")); /* !sun */
+ puts(_("f\tfix partition order")); /* !sun, !aix, !sgi */
#if ENABLE_FEATURE_SGI_LABEL
- puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */
+ puts(_("g\tcreate an IRIX (SGI) partition table"));/* sgi */
#endif
- puts(_("\th\tchange number of heads"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tp\tprint the partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\tr\treturn to main menu"));
- puts(_("\ts\tchange number of sectors/track"));
- puts(_("\tv\tverify the partition table"));
- puts(_("\tw\twrite table to disk and exit"));
+ puts(_("h\tchange number of heads"));
+ puts(_("p\tprint the partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("r\treturn to main menu"));
+ puts(_("s\tchange number of sectors/track"));
+ puts(_("v\tverify the partition table"));
+ puts(_("w\twrite table to disk and exit"));
}
}
#endif /* ADVANCED mode */
const struct systypes *types = get_sys_types();
for (i = 0; types[i].name; i++)
- if ((unsigned char )types[i].name[0] == type)
+ if ((unsigned char)types[i].name[0] == type)
return types[i].name + 1;
return _("Unknown");
ptes[i].part_table->sys_ind);
}
-void list_types(const struct systypes *sys)
+static void list_types(const struct systypes *sys)
{
- unsigned last[4], done = 0, next = 0, size;
+ enum { COLS = 3 };
+
+ unsigned last[COLS];
+ unsigned done, next, size;
int i;
- for (i = 0; sys[i].name; i++);
- size = i;
+ for (size = 0; sys[size].name; size++) /* */;
- for (i = 3; i >= 0; i--)
- last[3 - i] = done += (size + i - done) / (i + 1);
- i = done = 0;
+ done = 0;
+ for (i = COLS-1; i >= 0; i--) {
+ done += (size + i - done) / (i + 1);
+ last[COLS-1 - i] = done;
+ }
+ i = done = next = 0;
do {
- printf("%c%2x %-15.15s", i ? ' ' : '\n',
+ printf("%c%2x %-22.22s", i ? ' ' : '\n',
(unsigned char)sys[next].name[0],
- partition_type((unsigned char)sys[next].name[0]));
+ sys[next].name + 1);
next = last[i++] + done;
- if (i > 3 || next >= last[i]) {
+ if (i >= COLS || next >= last[i]) {
i = 0;
next = ++done;
}
"an extended partition first\n"));
} else {
char c, line[LINE_LENGTH];
- snprintf(line, sizeof(line), "%s\n %s\n p primary "
- "partition (1-4)\n",
- "Command action", (extended_offset ?
- "l logical (5 or over)" : "e extended"));
+ snprintf(line, sizeof(line),
+ "Command action\n"
+ " %s\n"
+ " p primary partition (1-4)\n",
+ (extended_offset ?
+ "l logical (5 or over)" : "e extended"));
while (1) {
c = read_nonempty(line);
if (c == 'p' || c == 'P') {
static void
bsd_menu(void)
{
- puts(_("Command action"));
- puts(_("\td\tdelete a BSD partition"));
- puts(_("\te\tedit drive data"));
- puts(_("\ti\tinstall bootstrap"));
- puts(_("\tl\tlist known filesystem types"));
- puts(_("\tm\tprint this menu"));
- puts(_("\tn\tadd a new BSD partition"));
- puts(_("\tp\tprint BSD partition table"));
- puts(_("\tq\tquit without saving changes"));
- puts(_("\tr\treturn to main menu"));
- puts(_("\ts\tshow complete disklabel"));
- puts(_("\tt\tchange a partition's filesystem id"));
- puts(_("\tu\tchange units (cylinders/sectors)"));
- puts(_("\tw\twrite disklabel to disk"));
+ puts(_("Command Action"));
+ puts(_("d\tdelete a BSD partition"));
+ puts(_("e\tedit drive data"));
+ puts(_("i\tinstall bootstrap"));
+ puts(_("l\tlist known filesystem types"));
+ puts(_("n\tadd a new BSD partition"));
+ puts(_("p\tprint BSD partition table"));
+ puts(_("q\tquit without saving changes"));
+ puts(_("r\treturn to main menu"));
+ puts(_("s\tshow complete disklabel"));
+ puts(_("t\tchange a partition's filesystem id"));
+ puts(_("u\tchange units (cylinders/sectors)"));
+ puts(_("w\twrite disklabel to disk"));
#if !defined(__alpha__)
- puts(_("\tx\tlink BSD partition to non-BSD partition"));
+ puts(_("x\tlink BSD partition to non-BSD partition"));
#endif
}
static int
edit_int(int def, char *mesg)
{
+ mesg = xasprintf("%s (%d): ", mesg, def);
do {
- fputs(mesg, stdout);
- printf(" (%d): ", def);
- if (!read_line())
- return def;
+ if (!read_line(mesg))
+ goto ret;
} while (!isdigit(*line_ptr));
- return atoi(line_ptr);
+ def = atoi(line_ptr);
+ ret:
+ free(mesg);
+ return def;
}
static void
else
dkbasename = "wd";
- printf(_("Bootstrap: %sboot -> boot%s (%s): "),
+ snprintf(path, sizeof(path), "Bootstrap: %sboot -> boot%s (%s): ",
dkbasename, dkbasename, dkbasename);
- if (read_line()) {
- line_ptr[strlen(line_ptr)-1] = '\0';
+ if (read_line(path)) {
dkbasename = line_ptr;
}
snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename);