/* finds and print all occurencies of commands from the history which * start with <cmd> * Returns the number of found entries on success, * and 0 if no such entry exists * * Peter Weilbacher 28Jun2004 */ int history_find_all(char *cmd) { int len; int found; int number = 0; /* each found entry increases this */ /* quote removal, copied from non-readline version */ if (*cmd == '"') cmd++; if (!*cmd) return 0; len = strlen(cmd); if (cmd[len - 1] == '"') cmd[--len] = 0; if (!*cmd) return 0; /* printf ("searching for all occurrences of '%s'\n", cmd); */ /* Output matching history entries in chronological order (not backwards * so we have to start at the beginning of the history list. */ history_set_pos(0); do { found = history_search_prefix(cmd, 1); /* Anchored backward search for prefix */ if (found == 0) { number++; printf("%5i %s\n", where_history() + history_base, current_history()->line); /* go one step back or you find always the same entry. */ if (!history_set_pos(where_history() + 1)) break; /* finished if stepping didn't work */ } /* (found == 0) */ } while (found > -1); return number; }
int _el_display_prev_hist() { if (where_history() > 0) { if (!_el_w2mb(_el_line_buffer, &rl_line_buffer)) { return -1; } replace_history_entry(where_history(), rl_line_buffer, NULL); _el_previous_history(); _el_display_history(); } return 0; }
int _el_display_first_hist() { if (where_history() > 0) { if (!_el_w2mb(_el_line_buffer, &rl_line_buffer)) { return -1; } replace_history_entry(where_history(), rl_line_buffer, NULL); _el_history_set_pos(1); _el_display_history(); } return 0; }
int _el_display_last_hist() { if (where_history() < history_length()) { if (!_el_w2mb(_el_line_buffer, &rl_line_buffer)) { return -1; } replace_history_entry(where_history(), rl_line_buffer, NULL); _el_history_set_pos(history_length() + 1); _el_display_history(); } return 0; }
int _el_display_next_hist() { if (where_history() < (history_length() - 1)) { if (!_el_w2mb(_el_line_buffer, &rl_line_buffer)) { return -1; } replace_history_entry(where_history(), rl_line_buffer, NULL); next_history(); _el_display_history(); } return 0; }
/* finds and print all occurencies of commands from the history which * start with <cmd> * Returns the number of found entries on success, * and 0 if no such entry exists * * Peter Weilbacher 28Jun2004 */ int history_find_all(char *cmd) { int len; int found; int number = 0; /* each found entry increases this */ /* quote removal, copied from non-readline version */ if (*cmd == '"') cmd++; if (!*cmd) return 0; len = strlen(cmd); if (cmd[len - 1] == '"') cmd[--len] = 0; if (!*cmd) return 0; /* printf ("searching for all occurrences of '%s'\n", cmd); */ /* Output matching history entries in chronological order (not backwards * so we have to start at the beginning of the history list. */ #if defined(HAVE_LIBREADLINE) found = history_set_pos(0); if (found == -1) { fprintf(stderr, "ERROR (history_find_all): could not rewind history\n"); return 0; } #else /* HAVE_LIBEDITLINE */ /* libedit's history_set_pos() does not work properly, so we manually go to oldest entry */ while (next_history()); #endif do { found = history_search_prefix(cmd, 1); /* Anchored backward search for prefix */ if (found == 0) { number++; #if defined(HAVE_LIBREADLINE) printf("%5i %s\n", where_history() + history_base, current_history()->line); /* go one step back or you find always the same entry. */ if (!history_set_pos(where_history() + 1)) break; /* finished if stepping didn't work */ #else /* HAVE_LIBEDITLINE */ /* libedit's history indices are reversed wrt GNU readline */ printf("%5i %s\n", history_length - where_history() + history_base, current_history()->line); /* go one step back or you find always the same entry. */ if (!previous_history()) break; /* finished if stepping didn't work */ #endif } /* (found == 0) */ } while (found > -1); return number; }
/* Load the history list from the history file. */ void load_history () { char *hf; /* Truncate history file for interactive shells which desire it. Note that the history file is automatically truncated to the size of HISTSIZE if the user does not explicitly set the size differently. */ set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE")); stupidly_hack_special_variables ("HISTFILESIZE"); /* Read the history in HISTFILE into the history list. */ hf = get_string_value ("HISTFILE"); if (hf && *hf) { struct stat buf; if (stat (hf, &buf) == 0) { read_history (hf); using_history (); history_lines_in_file = where_history (); } } }
void edit_deinit(const char *history_file, int (*filter_cb)(void *ctx, const char *cmd)) { rl_callback_handler_remove(); readline_free_completions(); eloop_unregister_read_sock(STDIN_FILENO); if (history_file) { /* Save command history, excluding lines that may contain * passwords. */ HIST_ENTRY *h; history_set_pos(0); while ((h = current_history())) { char *p = h->line; while (*p == ' ' || *p == '\t') p++; if (filter_cb && filter_cb(edit_cb_ctx, p)) { h = remove_history(where_history()); if (h) { os_free(h->line); free(h->data); os_free(h); } else next_history(); } else next_history(); } write_history(history_file); } }
/* Search the history list for STRING starting at absolute history position POS. If STRING begins with `^', the search must match STRING at the beginning of a history line, otherwise a full substring match is performed for STRING. DIR < 0 means to search backwards through the history list, DIR >= 0 means to search forward. */ static int noninc_search_from_pos (char *string, int pos, int dir) { int ret, old; old = where_history (); history_set_pos (pos); if (*string == '^') ret = history_search_prefix (string + 1, dir); else ret = history_search (string, dir); if (ret != -1) ret = where_history (); history_set_pos (old); return (ret); }
static int previoushistory(lua_State *L) { HIST_ENTRY *hist; if (!where_history()) hist = current_history(); else hist = previous_history(); push_history(L, hist); return 1; }
/* Search for a line in the history containing STRING. If DIR is < 0, the search is backwards through previous entries, else through subsequent entries. */ static void noninc_dosearch (char *string, int dir) { int oldpos, pos; HIST_ENTRY *entry; if (string == 0 || *string == '\0' || noninc_history_pos < 0) { DING (); return; } pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir); if (pos == -1) { /* Search failed, current history position unchanged. */ maybe_unsave_line (); rl_clear_message (); rl_point = 0; DING (); return; } noninc_history_pos = pos; oldpos = where_history (); history_set_pos (noninc_history_pos); entry = current_history (); #if defined (VI_MODE) if (rl_editing_mode != vi_mode) #endif history_set_pos (oldpos); { int line_len; line_len = strlen (entry->line); if (line_len >= rl_line_buffer_len) rl_extend_line_buffer (line_len); strcpy (rl_line_buffer, entry->line); } rl_undo_list = (UNDO_LIST *)entry->data; rl_end = strlen (rl_line_buffer); rl_point = 0; rl_clear_message (); if (saved_line_for_history) _rl_free_history_entry (saved_line_for_history); saved_line_for_history = (HIST_ENTRY *)NULL; }
static void add_history_permanent(char *input) { if (!input || !*input) return; if (last_hist_is_temp) { history_rem(history_length); last_hist_is_temp = 0; } last_hist_offset = -1; HIST_ENTRY *entry = history_get(history_length); if (entry && !strcmp(input, entry->line)) return; last_hist_offset = where_history(); add_history(input); if (history_file) append_history(1, history_file); }
//------------------------------------------------------------------------------ static int find_duplicate(const char* line) { HIST_ENTRY* hist_entry; using_history(); while (hist_entry = previous_history()) { if (strcmp(hist_entry->line, line) == 0) { return where_history(); } } return -1; }
/* Perhaps put back the current line if it has changed. */ int rl_maybe_replace_line (void) { HIST_ENTRY *temp; temp = current_history (); /* If the current line has changed, save the changes. */ if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) { temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list); xfree (temp->line); FREE (temp->timestamp); xfree (temp); } return 0; }
/* Process and free undo lists attached to each history entry prior to the current entry, inclusive, reverting each line to its saved state. This is destructive, and state about the current line is lost. This is not intended to be called while actively editing, and the current line is not assumed to have been added to the history list. */ void _rl_revert_all_lines (void) { int hpos; HIST_ENTRY *entry; UNDO_LIST *ul, *saved_undo_list; char *lbuf; lbuf = savestring (rl_line_buffer); saved_undo_list = rl_undo_list; hpos = where_history (); entry = (hpos == history_length) ? previous_history () : current_history (); while (entry) { if (ul = (UNDO_LIST *)entry->data) { if (ul == saved_undo_list) saved_undo_list = 0; /* Set up rl_line_buffer and other variables from history entry */ rl_replace_from_history (entry, 0); /* entry->line is now current */ entry->data = 0; /* entry->data is now current undo list */ /* Undo all changes to this history entry */ while (rl_undo_list) rl_do_undo (); /* And copy the reverted line back to the history entry, preserving the timestamp. */ FREE (entry->line); entry->line = savestring (rl_line_buffer); } entry = previous_history (); } /* Restore history state */ rl_undo_list = saved_undo_list; /* may have been set to null */ history_set_pos (hpos); /* reset the line buffer */ rl_replace_line (lbuf, 0); _rl_set_the_line (); /* and clean up */ xfree (lbuf); }
/* If this is an interactive shell, then append the lines executed this session to the history file. */ int maybe_save_shell_history () { int result = 0; if (history_lines_this_session) { char *hf = get_string_value ("HISTFILE"); if (hf && *hf) { struct stat buf; /* If the file doesn't exist, then create it. */ if (stat (hf, &buf) == -1) { int file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0666); if (file != -1) close (file); } /* Now actually append the lines if the history hasn't been stifled. If the history has been stifled, rewrite the history file. */ using_history (); if (history_lines_this_session <= where_history ()) { result = append_history (history_lines_this_session, hf); history_lines_in_file += history_lines_this_session; } else { result = write_history (hf); history_lines_in_file = history_lines_this_session; } history_lines_this_session = 0; } } return (result); }
/* Write the existing history out to the history file. */ void save_history () { char *hf = get_string_value ("HISTFILE"); if (hf && *hf) { struct stat buf; if (stat (hf, &buf) == 0) { /* Append only the lines that occurred this session to the history file. */ using_history (); if (history_lines_this_session < where_history ()) append_history (history_lines_this_session, hf); else write_history (hf); } } }
/* With an argument, move back that many history lines, else move to the beginning of history. */ int rl_vi_fetch_history (int count, int c) { int current = where_history (); /* Giving an argument of n means we want the nth command in the history file. The command number is interpreted the same way that the bash `history' command does it -- that is, giving an argument count of 450 to this command would get the command listed as number 450 in the output of `history'. */ if (rl_explicit_arg) { int wanted = history_base + current - count; if (wanted <= 0) rl_beginning_of_history (0, 0); else rl_get_previous_history (wanted, c); } else rl_beginning_of_history (count, 0); return (0); }
/* Meta-< goes to the start of the history. */ int rl_beginning_of_history (int count, int key) { return (rl_get_previous_history (1 + where_history (), key)); }
static int handle_hotkey2(int UNUSED(count), int hotkey, int ignore_history) { char *prefix, *postfix, *history, *histpos_as_string, *executing_keyseq; char *new_prefix, *new_postfix, *new_history, *new_histpos_as_string, *message; char *filter_food, *filtered, **fragments, *new_rl_line_buffer; int length, new_histpos; unsigned long int hash; static const unsigned int MAX_HISTPOS_DIGITS = 6; /* one million history items should suffice */ #ifdef HAVE_RL_EXECUTING_KEYSEQ /* i.e. if readline version is >= 6.3 */ executing_keyseq = mysavestring(rl_executing_keyseq); #else executing_keyseq = mysavestring("?"); *executing_keyseq = hotkey; /* The filter will only get the *last* byte of the key sequence that triggered rl_handle_hotkey */ #endif DPRINTF3(DEBUG_READLINE, "hotkey press (ignore_history == %d): %x (%s)", ignore_history, hotkey, mangle_string_for_debug_log(executing_keyseq, MANGLE_LENGTH)); if (hotkey == '\t') /* this would go horribly wrong with all the splitting on '\t' going on.... @@@ or pass key as a string e.g. "009" */ myerror(FATAL | NOERRNO, "Sorry, you cannot use TAB as an hotkey in rlwrap"); prefix = mysavestring(rl_line_buffer); prefix[rl_point] = '\0'; /* chop off just before cursor */ postfix = mysavestring(rl_line_buffer + rl_point); if (ignore_history) { histpos_as_string = mysavestring("0"); history = mysavestring(""); } else { histpos_as_string = as_string(where_history()); assert(strlen(histpos_as_string) <= MAX_HISTPOS_DIGITS); history = entire_history_as_one_string(); hash = hash_multiple(2, history, histpos_as_string); } /* filter_food = key + tab + prefix + tab + postfix + tab + history + tab + histpos + '\0' */ length = strlen(rl_line_buffer) + strlen(history) + MAX_HISTPOS_DIGITS + 5; filter_food = mymalloc(length); sprintf(filter_food, "%s\t%s\t%s\t%s\t%s", executing_keyseq, prefix, postfix, history, histpos_as_string); /* this is the format that the filter expects */ /* let the filter filter ...! */ filtered= pass_through_filter(TAG_HOTKEY, filter_food); /* OK, we now have to read back everything. There should be exactly 5 TAB-separated components*/ fragments = split_on_single_char(filtered, '\t', 5); message = fragments[0]; new_prefix = fragments[1]; new_postfix = fragments[2]; new_history = fragments[3]; new_histpos_as_string = fragments[4]; if (!ignore_history && hash_multiple(2, new_history, new_histpos_as_string) != hash) { /* history has been rewritten */ char **linep, **history_lines = split_on_single_char(new_history, '\n', 0); DPRINTF3(DEBUG_READLINE, "hash=%lx, new_history is %d bytes long, histpos <%s>", hash, (int) strlen(new_history), new_histpos_as_string); clear_history(); for (linep = history_lines; *linep; linep++) add_history(*linep); new_histpos = my_atoi(new_histpos_as_string); history_set_pos(new_histpos); free_splitlist(history_lines); } new_rl_line_buffer = add2strings(new_prefix, new_postfix); if ( (length = strlen(new_rl_line_buffer)) > 0 && new_rl_line_buffer[length - 1] == '\n') { new_rl_line_buffer[length - 1] = '\0'; rl_done = TRUE; return_key = (char) '\n'; assert(strchr(new_rl_line_buffer, '\n') == NULL); } rl_delete_text(0, strlen(rl_line_buffer)); rl_point = 0; rl_insert_text(new_rl_line_buffer); rl_point = strlen(new_rl_line_buffer); if (*message && *message != hotkey) { /* if message has been set (i.e. != hotkey) , and isn't empty: */ message = append_and_free_old(mysavestring(message), " "); /* put space (for readability) between the message and the input line .. */ message_in_echo_area(message); /* .. then write it to echo area */ } clear_line(); rl_on_new_line(); rl_redisplay(); free_splitlist(fragments); /* this will free all the fragments (and the list itself) in one go */ free_multiple(prefix, postfix, filter_food, executing_keyseq, filtered, new_rl_line_buffer, history, histpos_as_string, FMEND); return 0; }
static void wpa_cli_reconnect(void) { wpa_cli_close_connection(); ctrl_conn = wpa_cli_open_connection(ctrl_ifname); if (ctrl_conn) { printf("Connection to wpa_supplicant re-established\n"); #ifdef ANDROID if (wpa_ctrl_attach(monitor_conn) == 0) { #else if (wpa_ctrl_attach(ctrl_conn) == 0) { #endif wpa_cli_attached = 1; } else { printf("Warning: Failed to attach to " "wpa_supplicant.\n"); } } } static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, int action_monitor) { int first = 1; #ifdef ANDROID if (ctrl == NULL) { #else if (ctrl_conn == NULL) { #endif wpa_cli_reconnect(); return; } while (wpa_ctrl_pending(ctrl) > 0) { char buf[256]; size_t len = sizeof(buf) - 1; if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { buf[len] = '\0'; if (action_monitor) wpa_cli_action_process(buf); else { if (in_read && first) printf("\n"); first = 0; printf("%s\n", buf); } } else { printf("Could not read pending message.\n"); break; } } if (wpa_ctrl_pending(ctrl) < 0) { printf("Connection to wpa_supplicant lost - trying to " "reconnect\n"); wpa_cli_reconnect(); } } #ifdef CONFIG_READLINE static char * wpa_cli_cmd_gen(const char *text, int state) { static int i, len; const char *cmd; if (state == 0) { i = 0; len = os_strlen(text); } while ((cmd = wpa_cli_commands[i].cmd)) { i++; if (os_strncasecmp(cmd, text, len) == 0) return os_strdup(cmd); } return NULL; } static char * wpa_cli_dummy_gen(const char *text, int state) { return NULL; } static char ** wpa_cli_completion(const char *text, int start, int end) { return rl_completion_matches(text, start == 0 ? wpa_cli_cmd_gen : wpa_cli_dummy_gen); } #endif /* CONFIG_READLINE */ static void wpa_cli_interactive(void) { #define max_args 10 char cmdbuf[256], *cmd, *argv[max_args], *pos; int argc; #ifdef CONFIG_READLINE char *home, *hfile = NULL; #endif /* CONFIG_READLINE */ printf("\nInteractive mode\n\n"); #ifdef CONFIG_READLINE rl_attempted_completion_function = wpa_cli_completion; home = getenv("HOME"); if (home) { const char *fname = ".wpa_cli_history"; int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; hfile = os_malloc(hfile_len); if (hfile) { int res; res = os_snprintf(hfile, hfile_len, "%s/%s", home, fname); if (res >= 0 && res < hfile_len) { hfile[hfile_len - 1] = '\0'; read_history(hfile); stifle_history(100); } } } #endif /* CONFIG_READLINE */ do { #ifdef ANDROID wpa_cli_recv_pending(monitor_conn, 0, 0); #else wpa_cli_recv_pending(ctrl_conn, 0, 0); #endif #ifndef CONFIG_NATIVE_WINDOWS alarm(ping_interval); #endif /* CONFIG_NATIVE_WINDOWS */ #ifdef CONFIG_READLINE cmd = readline("> "); if (cmd && *cmd) { HIST_ENTRY *h; while (next_history()) ; h = previous_history(); if (h == NULL || os_strcmp(cmd, h->line) != 0) add_history(cmd); next_history(); } #else /* CONFIG_READLINE */ printf("> "); cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin); #endif /* CONFIG_READLINE */ #ifndef CONFIG_NATIVE_WINDOWS alarm(0); #endif /* CONFIG_NATIVE_WINDOWS */ if (cmd == NULL) break; #ifdef ANDROID wpa_cli_recv_pending(monitor_conn, 0, 0); #else wpa_cli_recv_pending(ctrl_conn, 0, 0); #endif pos = cmd; while (*pos != '\0') { if (*pos == '\n') { *pos = '\0'; break; } pos++; } argc = 0; pos = cmd; for (;;) { while (*pos == ' ') pos++; if (*pos == '\0') break; argv[argc] = pos; argc++; if (argc == max_args) break; if (*pos == '"') { char *pos2 = os_strrchr(pos, '"'); if (pos2) pos = pos2 + 1; } while (*pos != '\0' && *pos != ' ') pos++; if (*pos == ' ') *pos++ = '\0'; } if (argc) wpa_request(ctrl_conn, argc, argv); if (cmd != cmdbuf) os_free(cmd); } while (!wpa_cli_quit); #ifdef CONFIG_READLINE if (hfile) { /* Save command history, excluding lines that may contain * passwords. */ HIST_ENTRY *h; history_set_pos(0); while ((h = current_history())) { char *p = h->line; while (*p == ' ' || *p == '\t') p++; if (cmd_has_sensitive_data(p)) { h = remove_history(where_history()); if (h) { os_free(h->line); os_free(h->data); os_free(h); } else next_history(); } else next_history(); } write_history(hfile); os_free(hfile); } #endif /* CONFIG_READLINE */ }
debug_return_t enter_debugger (target_stack_node_t *p, file_t *p_target, int errcode, debug_enter_reason_t reason) { debug_return_t debug_return = debug_readloop; static bool b_init = false; static bool b_readline_init = false; char open_depth[MAX_NEST_DEPTH]; char close_depth[MAX_NEST_DEPTH]; unsigned int i = 0; last_stop_reason = reason; if ( in_debugger == DEBUGGER_QUIT_RC ) { return continue_execution; } if ( i_debugger_stepping > 1 || i_debugger_nexting > 1 ) { /* Don't stop unless we are here from a breakpoint. But do decrement the step count. */ if (i_debugger_stepping) i_debugger_stepping--; if (i_debugger_nexting) i_debugger_nexting--; if (!p_target->tracing) return continue_execution; } else if ( !debugger_on_error && !(i_debugger_stepping || i_debugger_nexting) && p_target && !p_target->tracing && -2 != errcode ) return continue_execution; /* Clear temporary breakpoints. */ if (p_target && p_target->tracing & BRK_TEMP) switch(last_stop_reason) { case DEBUG_BRKPT_AFTER_CMD: case DEBUG_BRKPT_BEFORE_PREREQ: case DEBUG_BRKPT_AFTER_PREREQ: p_target->tracing = BRK_NONE; default: ; } #ifdef HAVE_LIBREADLINE if (use_readline_flag && !b_readline_init) { rl_initialize (); using_history (); add_history (""); b_readline_init = true; } #endif if (!b_init) { cmd_initialize(); file2lines.ht_size = 0; b_init = true; } /* Set initial frame position reporting area: 0 is bottom. */ p_target_loc = NULL; psz_target_name = ""; i_stack_pos = 0; p_stack = p_stack_top = p; p_floc_stack = p_stack_floc_top; /* Get the target name either from the stack top (preferred) or the passed in target. */ if (p && p->p_target) { p_target_loc = &(p->p_target->floc); psz_target_name = (char *) p->p_target->name; } else if (p_target) { p_target_loc = &(p_target->floc); psz_target_name = (char *) p_target->name; } for (i=0; i<=makelevel && i < MAX_NEST_DEPTH-5; i++) { open_depth[i] = '<'; close_depth[i] = '>'; } if ( MAX_NEST_DEPTH - 5 == i ) { close_depth[i] = open_depth[i] = '.'; i++; close_depth[i] = open_depth[i] = '.'; i++; close_depth[i] = open_depth[i] = '.'; i++; } open_depth[i] = close_depth[i] = '\0'; in_debugger = true; if (errcode) { if (-1 == errcode) { printf("\n***Entering debugger because we encountered an error.\n"); } else if (-2 == errcode) { if (0 == makelevel) { printf("\nMakefile terminated.\n"); dbg_msg("Use q to quit or R to restart"); } else { printf("\nMakefile finished at level %d. Use R to restart\n", makelevel); dbg_msg("the makefile at this level or 's', 'n', or 'F' to continue " "in parent"); in_debugger = DEBUGGER_QUIT_RC; } } else { printf("\n***Entering debugger because we encountered a fatal error.\n"); dbg_errmsg("Exiting the debugger will exit make with exit code %d.", errcode); } } print_debugger_location(p_target, reason, NULL); /* Loop reading and executing lines until the user quits. */ for ( debug_return = debug_readloop; debug_return == debug_readloop || debug_return == debug_cmd_error; ) { char prompt[PROMPT_LENGTH]; char *line=NULL; char *s; if (setjmp(debugger_loop)) dbg_errmsg("Internal error jumped back to debugger loop"); else { #ifdef HAVE_LIBREADLINE if (use_readline_flag) { snprintf(prompt, PROMPT_LENGTH, "remake%s%d%s ", open_depth, where_history(), close_depth); line = readline (prompt); } else #endif { snprintf(prompt, PROMPT_LENGTH, "remake%s0%s ", open_depth, close_depth); printf("%s", prompt); if (line == NULL) line = calloc(1, 2048); line = fgets(line, 2048, stdin); if (NULL != line) chomp(line); } if ( line ) { if ( *(s=stripwhite(line)) ) { add_history (s); debug_return=execute_line(s); } else { add_history ("step"); debug_return=dbg_cmd_step(""); } free (line); } else { dbg_cmd_quit(NULL); } } } if (in_debugger != DEBUGGER_QUIT_RC) in_debugger=false; return debug_return; }
/* Search non-interactively through the history list. DIR < 0 means to search backwards through the history of previous commands; otherwise the search is for commands subsequent to the current position in the history list. PCHAR is the character to use for prompting when reading the search string; if not specified (0), it defaults to `:'. */ static void noninc_search (int dir, int pchar) { int saved_point, c, pmtlen; char *p; maybe_save_line (); saved_point = rl_point; /* Use the line buffer to read the search string. */ rl_line_buffer[0] = 0; rl_end = rl_point = 0; /* XXX - this needs fixing to work with the prompt expansion stuff - XXX */ pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0; p = xmalloc (2 + pmtlen); if (pmtlen) strcpy (p, rl_prompt); p[pmtlen] = pchar ? pchar : ':'; p[pmtlen + 1] = '\0'; rl_message (p, 0, 0); free (p); /* Read the search string. */ while ((c = rl_read_key ()) != '\0') { switch (c) { case CTRL('H'): case RUBOUT: if (rl_point == 0) { maybe_unsave_line (); rl_clear_message (); rl_point = saved_point; return; } rl_rubout (1, c); break; case CTRL('W'): rl_unix_word_rubout (1, c); break; case CTRL('U'): rl_unix_line_discard (1, c); break; case RETURN: case NEWLINE: goto dosearch; /* NOTREACHED */ break; case CTRL('C'): case CTRL('G'): maybe_unsave_line (); rl_clear_message (); rl_point = saved_point; DING (); return; default: rl_insert (1, c); break; } rl_redisplay (); } dosearch: /* If rl_point == 0, we want to re-use the previous search string and start from the saved history position. If there's no previous search string, punt. */ if (rl_point == 0) { if (!noninc_search_string) { DING (); return; } } else { /* We want to start the search from the current history position. */ noninc_history_pos = where_history (); if (noninc_search_string) free (noninc_search_string); noninc_search_string = strdup (rl_line_buffer); } noninc_dosearch (noninc_search_string, dir); }
static void wpa_cli_interactive(void) { #define max_args 10 char cmdbuf[256], *cmd, *argv[max_args], *pos; int argc; #ifdef CONFIG_READLINE char *home, *hfile = NULL; #endif /* CONFIG_READLINE */ printf("\nInteractive mode\n\n"); #ifdef CONFIG_READLINE rl_attempted_completion_function = wpa_cli_completion; home = getenv("HOME"); if (home) { const char *fname = ".wpa_cli_history"; int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1; hfile = os_malloc(hfile_len); if (hfile) { os_snprintf(hfile, hfile_len, "%s/%s", home, fname); hfile[hfile_len - 1] = '\0'; read_history(hfile); stifle_history(100); } } #endif /* CONFIG_READLINE */ do { wpa_cli_recv_pending(monitor_conn, 0, 0); #ifndef CONFIG_NATIVE_WINDOWS alarm(1); #endif /* CONFIG_NATIVE_WINDOWS */ #ifdef CONFIG_READLINE cmd = readline("> "); if (cmd && *cmd) { HIST_ENTRY *h; while (next_history()) ; h = previous_history(); if (h == NULL || os_strcmp(cmd, h->line) != 0) add_history(cmd); next_history(); } #else /* CONFIG_READLINE */ printf("> "); cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin); #endif /* CONFIG_READLINE */ #ifndef CONFIG_NATIVE_WINDOWS alarm(0); #endif /* CONFIG_NATIVE_WINDOWS */ if (cmd == NULL) break; wpa_cli_recv_pending(monitor_conn, 0, 0); pos = cmd; while (*pos != '\0') { if (*pos == '\n') { *pos = '\0'; break; } pos++; } argc = 0; pos = cmd; for (;;) { while (*pos == ' ') pos++; if (*pos == '\0') break; argv[argc] = pos; argc++; if (argc == max_args) break; if (*pos == '"') { char *pos2 = os_strrchr(pos, '"'); if (pos2) pos = pos2 + 1; } while (*pos != '\0' && *pos != ' ') pos++; if (*pos == ' ') *pos++ = '\0'; } if (argc) wpa_request(ctrl_conn, argc, argv); if (cmd != cmdbuf) os_free(cmd); } while (!wpa_cli_quit); #ifdef CONFIG_READLINE if (hfile) { /* Save command history, excluding lines that may contain * passwords. */ HIST_ENTRY *h; history_set_pos(0); h = next_history(); while (h) { char *p = h->line; while (*p == ' ' || *p == '\t') p++; if (os_strncasecmp(p, "pa", 2) == 0 || os_strncasecmp(p, "o", 1) == 0 || os_strncasecmp(p, "n", 1)) { h = remove_history(where_history()); if (h) { os_free(h->line); os_free(h->data); os_free(h); } h = current_history(); } else { h = next_history(); } } write_history(hfile); os_free(hfile); } #endif /* CONFIG_READLINE */ }