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); } }
/* Move down to the next history line. */ int rl_get_next_history (int count, int key) { HIST_ENTRY *temp; if (count < 0) return (rl_get_previous_history (-count, key)); if (count == 0) return 0; rl_maybe_replace_line (); /* either not saved by rl_newline or at end of line, so set appropriately. */ if (_rl_history_saved_point == -1 && (rl_point || rl_end)) _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point; temp = (HIST_ENTRY *)NULL; while (count) { temp = next_history (); if (!temp) break; --count; } if (temp == 0) rl_maybe_unsave_line (); else { rl_replace_from_history (temp, 0); _rl_history_set_point (); } return 0; }
static void readline_cmd_handler(char *cmd) { 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(); } if (cmd == NULL) { edit_eof_cb(edit_cb_ctx); return; } trunc_nl(cmd); edit_cmd_cb(edit_cb_ctx, cmd); }
bool ViCommandMode::handle_key_press( const Glib::ustring &key_str ) { if (key_str == "<Space>") { m_cmd += " "; } else if (key_str == "<CR>") { execute( m_cmd ); m_vi->set_mode(vi_normal); return true; } else if (key_str == "<BS>") { m_cmd = m_cmd.substr(0, m_cmd.length() - 1); if (m_cmd.length() == 0) { m_vi->set_mode(vi_normal); return true; } } else if (key_str == "<Up>") { m_cmd = next_history(Backward, m_cmd[0]); } else if (key_str == "<Down>") { m_cmd = next_history(Forward, m_cmd[0]); } else { m_cmd += key_str; } m_vi->show_message("%s", m_cmd.data()); return true; }
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; }
/* * Reverse the above encoding */ static void decode_history(void) { HIST_ENTRY *cur_hist; char *cur_ptr; history_set_pos(0); for (cur_hist = current_history(); cur_hist; cur_hist = next_history()) { /* some platforms declare HIST_ENTRY.line as const char * */ for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++) if (*cur_ptr == NL_IN_HISTORY) *cur_ptr = '\n'; } }
char *gnu_history_entry(int ind, int time) { HIST_ENTRY *entry = NULL; if (ind == 0) entry = current_history(); else if (ind < 0) entry = previous_history(); else if (ind > 0) entry = next_history(); if (entry == NULL) return NULL; return (time == 0 ? entry->line : entry->timestamp); }
static int rl_history_search_internal (int count, int direction) { HIST_ENTRY *temp, *old_temp; int line_len; maybe_save_line (); temp = old_temp = (HIST_ENTRY *)NULL; while (count) { temp = (direction < 0) ? previous_history () : next_history (); if (!temp) break; if (STREQN (rl_line_buffer, temp->line, rl_point)) { /* Don't find multiple instances of the same line. */ if (prev_line_found && STREQ (prev_line_found, temp->line)) continue; if (direction < 0) old_temp = temp; prev_line_found = temp->line; count--; } } if (!temp) { if (direction < 0 && old_temp) temp = old_temp; else { maybe_unsave_line (); DING (); return 1; } } line_len = strlen (temp->line); if (line_len >= rl_line_buffer_len) rl_extend_line_buffer (line_len); strcpy (rl_line_buffer, temp->line); rl_undo_list = (UNDO_LIST *)temp->data; rl_end = line_len; return 0; }
static int nexthistory(lua_State *L) { HIST_ENTRY *hist = next_history(); push_history(L, hist); return 1; }
static void ProcessEvent() { char intext[10]; KeySym keysym; XComposeStatus cs; int i, n, count; XEvent ev; HIST_ENTRY *hist; /* History entry */ char is_hist; XNextEvent (condpy, &ev); is_hist = 0; switch (ev.type) { case Expose: if (ev.xexpose.count == 0) Redraw (); break; case ConfigureNotify: width = ev.xconfigure.width; height = ev.xconfigure.height; Resize (width / font_width, height / font_height); break; case KeyPress: // count = XLookupString (&ev.xkey, intext, 10, &keysym, &cs); // intext[count] = 0; count = 1; intext[0] = ev.xkey.keycode; intext[1] = 0; if (count == 1) { switch (intext[0]) { case '\r': intext[0] = '\n'; break; #if !defined(STNDALN) case '': hist = previous_history(); is_hist = 1; break; case '': hist = next_history(); is_hist = 1; break; #endif } } #if !defined(STNDALN) /* Process history */ if ( is_hist ) { if(hist) { char *dst = text + ncols * row + 4; memset(dst,' ',col-3); /* clean to EOL */ col = 4; PutString(hist->line); PutChar (0); RedrawRow(); } break; } #endif #ifdef OBSOLETE /* as XLookupString is broken */ else switch (keysym) { case XK_Return: case XK_Linefeed: intext[0] = '\n'; intext[1] = 0; break; case XK_Tab: intext[0] = '\t'; intext[1] = 0; break; case XK_BackSpace: intext[0] = '\b'; intext[1] = 0; break; case XK_Delete: break; case XK_Left: break; case XK_Right: break; case XK_Down: break; case XK_Up: break; } #endif /* OBSOLETE */ if (intext[0] ) { if (intext[0] == '\n') { char *dst = text + ncols * row + plen; strncpy(grads_cmd,dst,1024); got_grads_cmd = 1; /* signal nxtcmd() that we got a command */ } PutChar (intext[0]); RedrawRow(); strcat (my_stdin_buf, intext); if ( intext[0] == '\n' ) { ProcessOutput (my_stdin_buf); my_stdin_buf[0] = 0; } } break; } }
static int read_debug_line(const char **outbuffer, void *cookie) { int pos = 0; int escape_level = 0; #if CONSOLE_ENABLE_HISTORY uint history_cursor = start_history_cursor(); #endif char *buffer = debug_buffer; for (;;) { /* loop until we get a char */ int c; if ((c = getchar()) < 0) continue; // TRACEF("c = 0x%hhx\n", c); if (escape_level == 0) { switch (c) { case '\r': case '\n': if (echo) putchar('\n'); goto done; case 0x7f: // backspace or delete case 0x8: if (pos > 0) { pos--; fputc('\b', stdout); putchar(' '); fputc('\b', stdout); // move to the left one } break; case 0x1b: // escape escape_level++; break; default: buffer[pos++] = c; if (echo) putchar(c); } } else if (escape_level == 1) { // inside an escape, look for '[' if (c == '[') { escape_level++; } else { // we didn't get it, abort escape_level = 0; } } else { // escape_level > 1 switch (c) { case 67: // right arrow buffer[pos++] = ' '; if (echo) putchar(' '); break; case 68: // left arrow if (pos > 0) { pos--; if (echo) { fputc('\b', stdout); // move to the left one putchar(' '); fputc('\b', stdout); // move to the left one } } break; #if CONSOLE_ENABLE_HISTORY case 65: // up arrow -- previous history case 66: // down arrow -- next history // wipe out the current line while (pos > 0) { pos--; if (echo) { fputc('\b', stdout); // move to the left one putchar(' '); fputc('\b', stdout); // move to the left one } } if (c == 65) strlcpy(buffer, prev_history(&history_cursor), LINE_LEN); else strlcpy(buffer, next_history(&history_cursor), LINE_LEN); pos = strlen(buffer); if (echo) fputs(buffer, stdout); break; #endif default: break; } escape_level = 0; } /* end of line. */ if (pos == (LINE_LEN - 1)) { fputs("\nerror: line too long\n", stdout); pos = 0; goto done; } } done: // dprintf("returning pos %d\n", pos); // null terminate buffer[pos] = 0; #if CONSOLE_ENABLE_HISTORY // add to history add_history(buffer); #endif // return a pointer to our buffer *outbuffer = buffer; return pos; }
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 */ }
int main(int argc, char *argv[], char *envp[]) { read_config(); //read the config file char c; //reading one letter at time here //building a command line which will eventually get parsed line = (char *)malloc(sizeof(char) * 100); memset(line,0,100); char *cmd = (char *)malloc(sizeof(char) * 100); //the program (command w/o args) char *printBuff = (char *)malloc(sizeof(char)*100); //a printing buffer (for use with raw tty) //holder for history if stuff is typed, then history is used to go back to typed stuff char *historyHold = (char *)malloc(sizeof(char)*100); path = (char*)malloc(sizeof(char)*100); fullPath = (char*)malloc(sizeof(char)*100); memset(printBuff,0,100); memset(historyHold,0,100); memset(cmd,0,100); signal(SIGINT, handle_sig); //register interrupt signal (for CTRL+C) int promptLen; //making sure we dont backspace the prompt int fromHistory = 0; //a type of check to see if our line is from history (not user typed) if(fork() == 0) { execve("/usr/bin/clear", argv, envp); //simply clear the screen exit(1); } else { wait(NULL); //wait to clear screen } get_path(); //gets the 2dir path for prompt tty_raw_mode();//set terminal into raw mode sprintf(printBuff,"%s:%s",path,PROMPT); //build print buff promptLen = strlen(printBuff); curPos = promptLen; //leave a space write(1,printBuff,promptLen); //print initial prompt memset(printBuff,0,100); //clear printBuff clear_args(); //just get any initial crap out /* MAIN LOOP */ while(1) { read(0,&c,1); //read 1 character from stdin if(((c >= 32) && c!=127) || c == 10) { //here, we only want to process characters that are //"readable" (or enter). special characters will be //handled differently tabPressNo = 0; //they didnt press tab write(1,&c,1); //write char (echo is off for raw mode) ++curPos; switch(c) { case '\n': //end of the line (enter was pressed after input) if(line[0] == '\0') { //they didnt type anything sprintf(printBuff,"%s:%s",path,PROMPT); write(1,printBuff,promptLen); } else if(strcmp(line,"exit")==0) { printf("\n"); //for niceness quit_raw_mode(); //play nice and restore term state return 0; //quit if they type "exit" } else { //prepare to actually process strncat(line,"\0",1); if(line[0] != '!') { add_history(line); //add command to history } int pipe = 0; int separ = check_separ(line); if(!separ){ pipe = check_pipe(line); } if(!separ && !pipe){ //try to execute the command if there werent pipes or semicolons parse_args(line); //build array of arguments strcpy(cmd, args[0]); //cmd = program to run execute(cmd); clear_args(); //resets all arg array strings } c = '\0'; memset(cmd, 0, 100); //clear the cmd array //reprint prompt sprintf(printBuff,"%s:%s",path,PROMPT); promptLen = strlen(printBuff); curPos = promptLen; write(1,printBuff,promptLen); } memset(line,0,100); //clear line array memset(historyHold,0,100);//clear history hold break; default: strncat(line, &c, 1);//build the line break; } } else if(c == 8) { //backspace pressed if(curPos > promptLen) { backspace(); //backspace until we reach prompt line[strlen(line)-1] = 0; //thank god this finally works --curPos; } } else if(c == 27) { //the user pressed some sort of //escape sequence char c1; char c2; read(0,&c1,1); read(0,&c2,1); //ok, we have the two parts of the //escape sequence in c1 and c2 if(c1 == 91 && c2 == 65) { //this is the escape for the up arrow //which we want to use for history //browsing char *tmpLine; tmpLine = prev_history(); if(tmpLine != 0) { if(line[0] != '\0' && fromHistory==0) { //store what user currently has typed (if anything) memset(historyHold,0,100); strncpy(historyHold,line,strlen(line)); } clear_line(strlen(line)); //clears whatever is at the prompt memset(line,0,100); strncpy(line,tmpLine,strlen(tmpLine)); //copy this command free(tmpLine); //play nice write(1,line,strlen(line)); //write old command fromHistory = 1; //current line has been replaced by history curPos = strlen(line) + promptLen; //so we know where are } } else if(c1 == 91 && c2 == 66) { //this is the escape for the down arrow //which should make us go "forward" //in history (if we are back in it) char *tmpLine; tmpLine = next_history(); //get the next history if(tmpLine != 0) { //next_history gave us a line clear_line(strlen(line)); //clear old line from screen memset(line,0,100); //clear old line in mem strncpy(line,tmpLine,strlen(tmpLine)); //copy new line to old line write(1,line,strlen(line)); //write new line to screen curPos = strlen(line) + promptLen; //update pos free(tmpLine); } else if(historyHold[0] != '\0') { //if we dont have a next_line, lets see if //we had some buffer before browsing history clear_line(strlen(line)); memset(line,0,100); strncpy(line,historyHold,strlen(historyHold)); write(1,line,strlen(line)); curPos = strlen(line) +promptLen; fromHistory = 0; //back to user typed } else { //it was blank before history was browsed clear_line(strlen(line)); memset(line,0,100); curPos = promptLen; } } } else if(c == '\t') { //tab press. should i dare try to do tab //completion? i guess... //if this is the 2nd time in a row pressing tab //they want a listing of everything that can be //completed if(tabPressNo) { //print everything in tabHold tabPressNo = 0; if(tabCompHold[0] != NULL) { int i = 1; char *x = tabCompHold[0]; char *tmp = (char*)malloc(sizeof(char)*100); memset(tmp,0,100); write(1,"\n",1); while(x != NULL) { sprintf(tmp,"%s\t",x); write(1,tmp,strlen(tmp)); memset(tmp,0,100); x = tabCompHold[i]; ++i; } write(1,"\n",1); //reprint prompt sprintf(printBuff,"%s:%s",path,PROMPT); promptLen = strlen(printBuff); curPos = promptLen + strlen(line); write(1,printBuff,promptLen); //write the line again write(1,line,strlen(line)); clear_tab_hold(); } } else { //otherwise just let tab_complete //print a single completion char *tabcomp; tabcomp = tab_complete(line); if(tabcomp != NULL) { //tab comp found a single thing, so //lets just complete it int i = 1; char c = tabcomp[0]; while(c!='\0') { write(1,&c,1); strncat(line,&c,1); c = tabcomp[i]; ++i; } curPos += strlen(tabcomp); //set our new position free(tabcomp); } ++tabPressNo; } } else if(c == '\177') { //other form of backspace if(curPos > promptLen) { backspace(); //backspace until we reach prompt line[strlen(line)-1] = 0; //thank god this finally works --curPos; } } memset(printBuff,0,100); //clear printing buffer } printf("\n"); //for niceness quit_raw_mode(); //so we dont get stuck in it return 0; //goodbye }
/* main readline function */ char *readline(const char *prompt) { wchar_t buf[_EL_CONSOLE_BUF_LEN]; char **array = NULL; char *ret_string = NULL; int start = 0; int end = 0; int compl_pos = -1; int n = 0; int index = 0; int len = 0; int line_len = 0; int old_width = 0; int width = 0; UINT32 ctrl = 0; UINT32 special = 0; COORD coord; DWORD count = 0; INPUT_RECORD irBuffer; CONSOLE_SCREEN_BUFFER_INFO sbInfo; _el_ctrl_c_pressed = FALSE; _el_line_buffer = NULL; _el_temp_print = NULL; _el_next_compl = NULL; rl_line_buffer = NULL; _el_file_name = NULL; _el_dir_name = NULL; _el_old_arg = NULL; _el_wide = NULL; _el_text = NULL; _el_text_mb = NULL; _el_compl_array = NULL; _el_completer_word_break_characters = NULL; rl_point = 0; rl_attempted_completion_over = 0; _el_compl_index = 0; _el_n_compl = 0; _el_h_in = NULL; _el_h_out = NULL; wcscpy_s(_el_basic_file_break_characters, _EL_MAX_FILE_BREAK_CHARACTERS, _EL_BASIC_FILE_BREAK_CHARACTERS); memset(&coord, 0, sizeof(COORD)); memset(buf, 0, _EL_CONSOLE_BUF_LEN * sizeof(wchar_t)); memset(&irBuffer, 0, sizeof(INPUT_RECORD)); /* allocate buffers */ _el_line_buffer_size = _EL_BUF_LEN + 1; _el_line_buffer = (wchar_t *)malloc(_el_line_buffer_size * sizeof(wchar_t)); if (!_el_mb2w((char *)rl_basic_word_break_characters, &_el_basic_word_break_characters)) { _el_clean_exit(); return NULL; } if (rl_completer_word_break_characters) { if (!_el_mb2w((char *)rl_completer_word_break_characters, &_el_completer_word_break_characters)) { _el_clean_exit(); return NULL; } } if (!(_el_line_buffer)) { _el_clean_exit(); return NULL; } memset(_el_line_buffer, 0, _el_line_buffer_size * sizeof(wchar_t)); rl_attempted_completion_over = 0; _el_print = (wchar_t *)malloc(_el_line_buffer_size * sizeof(wchar_t)); if (!(_el_print)) { _el_clean_exit(); return NULL; } memset(_el_print, 0, _el_line_buffer_size * sizeof(wchar_t)); rl_prompt = _strdup(prompt); if (!(rl_prompt)) { _el_clean_exit(); return NULL; } if (!_el_mb2w((char *)prompt, &_el_prompt)) { _el_clean_exit(); return NULL; } _el_prompt_len = (int)wcslen(_el_prompt); /* get I/O handles for current console */ _el_h_in = GetStdHandle(STD_INPUT_HANDLE); _el_h_out = GetStdHandle(STD_OUTPUT_HANDLE); if ((!(_el_h_in)) || (!(_el_h_out))) { _el_clean_exit(); return NULL; } /* set console modes */ _el_prev_in_cm_saved = GetConsoleMode(_el_h_in, &_el_prev_in_cm); _el_prev_out_cm_saved = GetConsoleMode(_el_h_out, &_el_prev_out_cm); SetConsoleMode(_el_h_in, ENABLE_PROCESSED_INPUT | ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE); SetConsoleMode(_el_h_out, ENABLE_PROCESSED_OUTPUT); SetConsoleCtrlHandler((PHANDLER_ROUTINE) _el_signal_handler, TRUE); rl_point = 0; while ((buf[0] != VK_RETURN) && (!_el_ctrl_c_pressed) && _el_line_buffer) { /* get screen buffer info from the current console */ if (!GetConsoleScreenBufferInfo(_el_h_out, &sbInfo)) { _el_clean_exit(); return NULL; } _el_temp_print_size = sbInfo.dwSize.X + 1; if (!(_el_temp_print = realloc(_el_temp_print, _el_temp_print_size * sizeof(wchar_t)))) { _el_clean_exit(); return NULL; } _el_temp_print[0] = _T('\0'); /* compute the current visible console width */ width = sbInfo.srWindow.Right - sbInfo.srWindow.Left + 1; /* if the user has changed the window size update the view */ if (old_width != width) { line_len = (int)wcslen(_el_line_buffer); sbInfo.dwCursorPosition.X = 0; if (old_width) { n = (_el_prompt_len + line_len - 1) / old_width; sbInfo.dwCursorPosition.Y -= n; coord.Y = sbInfo.dwCursorPosition.Y; } if (!SetConsoleCursorPosition(_el_h_out, sbInfo.dwCursorPosition)) { _el_clean_exit(); return NULL; } if (_el_print_string(_el_prompt)) { _el_clean_exit(); return NULL; } if (_el_set_cursor(_el_prompt_len)) { _el_clean_exit(); return NULL; } if (_el_print_string(_el_line_buffer)) { _el_clean_exit(); return NULL; } if (_el_set_cursor(line_len)) { _el_clean_exit(); return NULL; } if (old_width && (old_width < width)) { coord.X = 0; coord.Y += (_el_prompt_len + line_len - 1) / width + 1; FillConsoleOutputCharacter(_el_h_out, _T(' '), sbInfo.dwSize.X * (n + 2), coord, &count); } } old_width = width; /* wait for console events */ if (!PeekConsoleInput(_el_h_in, &irBuffer, 1, &count)) { _el_clean_exit(); return NULL; } if (count) { if ((irBuffer.EventType == KEY_EVENT) && irBuffer.Event.KeyEvent.bKeyDown) { /* the user pressed a key */ ctrl = (irBuffer.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)); if (irBuffer.Event.KeyEvent.uChar.UnicodeChar == _T('\n')) { if (!ReadConsoleInput(_el_h_in, &irBuffer, 1, &count)) { _el_clean_exit(); return NULL; } buf[0] = VK_RETURN; continue; } if (irBuffer.Event.KeyEvent.uChar.UnicodeChar == _T('\0')) { /* if it is a special key, just remove it from the buffer */ if (!ReadConsoleInput(_el_h_in, &irBuffer, 1, &count)) { _el_clean_exit(); return NULL; } special = irBuffer.Event.KeyEvent.wVirtualKeyCode; /* parse the special key */ switch (special) { /* arrow left, arrow right HOME and END keys */ case VK_LEFT: case VK_RIGHT: case VK_HOME: case VK_END: if (_el_move_cursor(special, ctrl)) { _el_clean_exit(); return NULL; } break; /* arrow up: display previous history element (if any) after recording the current command line */ case VK_UP: if (_el_display_prev_hist()) { _el_clean_exit(); return NULL; } break; /* page up: display the first history element (if any) after recording the current command line */ case VK_PRIOR: if (_el_display_first_hist()) { _el_clean_exit(); return NULL; } break; /* arrow down: display next history element (if any) after recording the current command line */ case VK_DOWN: if (_el_display_next_hist()) { _el_clean_exit(); return NULL; } break; case VK_NEXT: /* page down: display last history element (if any) after recording the current command line */ if (_el_display_last_hist()) { _el_clean_exit(); return NULL; } break; /* delete char */ case VK_DELETE: if (rl_point != wcslen(_el_line_buffer)) { if (_el_delete_char(VK_DELETE, 1)) { _el_clean_exit(); return NULL; } _el_compl_index = 0; compl_pos = -1; } break; } } else { /* if it is a normal key, remove it from the buffer */ memset(buf, 0, _EL_CONSOLE_BUF_LEN * sizeof(wchar_t)); if (!ReadConsole(_el_h_in, buf, 1, &count, NULL)) { _el_clean_exit(); return NULL; } /* then parse it */ switch (buf[0]) { /* backspace */ case VK_BACK: if (rl_point) { _el_compl_index = 0; compl_pos = -1; if (_el_delete_char(VK_BACK, 1)) { _el_clean_exit(); return NULL; } } break; /* TAB: do completion */ case VK_TAB: if ((!array) || (rl_point != compl_pos)) { _el_free_array(array); index = 0; if (_el_text) { free(_el_text); _el_text = NULL; } if (!(_el_text = _el_get_compl_text(&start, &end))) { _el_clean_exit(); return NULL; } if (_el_old_arg) { _el_old_arg[0] = _T('\0'); } if (!_el_w2mb(_el_text, &_el_text_mb)) { _el_clean_exit(); return NULL; } if (!_el_w2mb(_el_line_buffer, &rl_line_buffer)) { _el_clean_exit(); return NULL; } array = (rl_attempted_completion_function ? rl_attempted_completion_function(_el_text_mb, start, end) : rl_completion_matches(_el_text_mb, (rl_completion_entry_function ? rl_completion_entry_function : rl_filename_completion_function))); if (!array) { _el_clean_exit(); return NULL; } } if (!array[index]) { index = 0; } if (array[index]) { if (!_el_mb2w(array[index], &_el_next_compl)) { _el_clean_exit(); return NULL; } len = 0; if (_el_old_arg) { len = (int)wcslen(_el_old_arg); #if 0 fwprintf(stderr, _T("VK_TAB) _el_old_arg = '%s', len = %d\n"), _el_old_arg, len); fflush(stderr); #endif } if (!len) { len = (int)wcslen(_el_text); } if (len) { if (_el_delete_char(VK_BACK, len)) { _el_clean_exit(); return NULL; } } len = (int)wcslen(_el_next_compl); if (!(_el_old_arg = realloc(_el_old_arg, (len + 1) * sizeof(wchar_t)))) { return NULL; } _el_old_arg[len] = _T('\0'); memcpy(_el_old_arg, _el_next_compl, len * sizeof(wchar_t)); line_len = (int)wcslen(_el_line_buffer); if (_el_insert_char(_el_next_compl, len)) { _el_clean_exit(); return NULL; } free(_el_next_compl); _el_next_compl = NULL; compl_pos = ((rl_point && (!wcschr(_el_completer_word_break_characters ? _el_completer_word_break_characters : _el_basic_word_break_characters, _el_line_buffer[rl_point - 1]))) ? rl_point : -1); ++index; } break; /* ENTER: move the cursor to end of line, then return to the caller program */ case VK_RETURN: if (_el_set_cursor((int)wcslen(_el_line_buffer) - rl_point)) { _el_clean_exit(); return NULL; } break; /* delete word */ case 0x17: /* CTRL + W */ if (ctrl) { if (!rl_point) { break; } n = 1; while (((rl_point - n) > 0) && (iswspace(_el_line_buffer[rl_point - n]))) { ++n; } while ((rl_point - n) && (!iswspace(_el_line_buffer[rl_point - n]))) { ++n; } if (rl_point - n) { --n; } _el_compl_index = 0; compl_pos = -1; if (_el_delete_char(VK_BACK, n)) { _el_clean_exit(); return NULL; } break; } /* delete until end of line */ case 0x0B: /* CTRL + K */ if (ctrl) { line_len = (int)wcslen(_el_line_buffer); if (rl_point < line_len) { _el_compl_index = 0; compl_pos = -1; if (_el_delete_char(VK_DELETE, line_len - rl_point)) { _el_clean_exit(); return NULL; } } break; } /* beginning-of-line */ case 0x01: /* CTRL + A */ if (_el_move_cursor(VK_HOME, 0)) { _el_clean_exit(); return NULL; } break; /* end-of-line */ case 0x05: /* CTRL + E */ if (_el_move_cursor(VK_END, 0)) { _el_clean_exit(); return NULL; } break; /* forward-char */ case 0x06: /* CTRL + F */ if (_el_move_cursor(VK_RIGHT, 0)) { _el_clean_exit(); return NULL; } break; /* backward-char */ case 0x02: /* CTRL + B */ if (_el_move_cursor(VK_LEFT, 0)) { _el_clean_exit(); return NULL; } break; /* previous-line */ case 0x10: /* CTRL + P */ if (_el_display_prev_hist()) { _el_clean_exit(); return NULL; } break; /* next-line */ case 0x0E: /* CTRL + N */ if (_el_display_next_hist()) { _el_clean_exit(); return NULL; } break; /* delete char */ case 0x04: /* CTRL + D */ if (rl_point != wcslen(_el_line_buffer)) { if (_el_delete_char(VK_DELETE, 1)) { _el_clean_exit(); return NULL; } _el_compl_index = 0; compl_pos = -1; } break; /* if it is a printable character, print it NOTE: I have later commented out the iswprint() check since for instance it prevents the euro sign from being printed */ default: /*if (iswprint(buf[0])) {*/ _el_compl_index = 0; compl_pos = -1; if (_el_insert_char(buf, 1)) { _el_clean_exit(); return NULL; } /*}*/ } } } /* if it was not a keyboard event, just remove it from buffer */ else if (!ReadConsoleInput(_el_h_in, &irBuffer, 1, &count)) { _el_clean_exit(); return NULL; } } else { /* wait for console input */ WaitForSingleObject(_el_h_in, INFINITE); } } printf("\n"); while (next_history()); previous_history(); /* if CTRL+C has been pressed, return an empty string */ if (_el_line_buffer) { if (_el_ctrl_c_pressed) { n = (int)wcslen(_el_line_buffer) - rl_point; if (n) { _el_set_cursor(n); } _el_line_buffer[0] = _T('\0'); } _el_w2mb(_el_line_buffer, &rl_line_buffer); ret_string = _strdup(rl_line_buffer); } _el_clean_exit(); return ret_string; }
/** * Binds the down arrow key to be used to return more recent commands * ran in the shell. * Note: Params and returned int are unused. */ int bindDown(int count, int key) { HIST_ENTRY * next = next_history(); printf(next->line); 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 */ }