Beispiel #1
0
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);
	}
}
Beispiel #2
0
/* 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;
}
Beispiel #3
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);
}
Beispiel #4
0
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;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
0
/*
 * 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';
	}
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
}
Beispiel #11
0
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;

    }
}
Beispiel #12
0
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;
}
Beispiel #13
0
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 */
}
Beispiel #14
0
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
}
Beispiel #15
0
/*
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;
}
Beispiel #16
0
/**
* 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 */
}