Пример #1
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.
     */
    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;
}
Пример #2
0
/* 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;
}
Пример #3
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;
}
Пример #4
0
int cli_init(struct parser_state *_state)
{
	const char *home;

	rl_readline_name = "nft";
	rl_instream  = stdin;
	rl_outstream = stdout;

	rl_callback_handler_install("nft> ", cli_complete);
	rl_attempted_completion_function = cli_completion;

	home = getenv("HOME");
	if (home == NULL)
		home = "";
	snprintf(histfile, sizeof(histfile), "%s/%s", home, CMDLINE_HISTFILE);

	read_history(histfile);
	history_set_pos(history_length);

	state	= _state;
	scanner = scanner_init(state);

	while (!eof)
		rl_callback_read_char();
	return 0;
}
Пример #5
0
//------------------------------------------------------------------------------
static void load_history()
{
    char buffer[1024];
    get_history_file_name(buffer, sizeof(buffer));
    read_history(buffer);
    history_set_pos(history_length);
}
Пример #6
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);
	}
}
Пример #7
0
/* 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);
}
Пример #8
0
/* Reading and Writing the librline context. {{{*/
int rline_read_history(struct rline *rline, const char *file)
{
    if (!rline)
        return -1;

    using_history();
    read_history(file);
    history_set_pos(history_length);

    return 0;
}
Пример #9
0
int _el_display_last_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);
        history_set_pos(history_length() - 1);
        _el_display_history();
    }

    return 0;
}
Пример #10
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';
	}
}
Пример #11
0
Файл: pcx11e.c Проект: cjg/grads
int nxtcmd (char *cmd, char *prompt)
{
    int i, len, past=0, cnt=0;

    printf ("%s ",prompt);  /* this is actually redirected by console() */
    plen = strlen(prompt)+1;

    past = cnt = 0;
    if ( x11_initialized ) {
        got_grads_cmd = 0;           /* fresh as new */
        while (1) {
            console();        /* console manager: handles stdio */
            if(got_grads_cmd) {
                strcpy(cmd,grads_cmd);
                got_grads_cmd = 0;             /* fresh as new */
                len = strlen(cmd);
#if !defined(STNDALN)
                if(len>0) {
                    add_history(cmd);                  /* add to the history list */
                    history_set_pos(history_length);
                }
#endif
                return(len);
            }
        }

    } else {   /* do as in regular grads */

        while (1) {
            *cmd = getchar();
            if (*cmd == EOF) {
                return(-1);
            }
            if (*cmd == '\n') {
                cmd++;
                *cmd = '\0';
                return(cnt);
            }
            if (past || *cmd != ' ') {
                cmd++;
                cnt++;
                past = 1;
            }
        }
    }
}
Пример #12
0
static int down_callback(int count, int key) {
    reset_indent();
    int j = line_end(rl_point);
    if (j < rl_end) {
        int i = line_start(rl_point);
        if (i == 0) rl_point += prompt_length;
        rl_point += j - i + 1;
        int k = line_end(j+1);
        if (rl_point > k) rl_point = k;
        return 0;
    } else {
        if (last_hist_offset >= 0) {
            history_set_pos(last_hist_offset);
            last_hist_offset = -1;
        }
        return rl_get_next_history(count, key);
    }
}
Пример #13
0
Файл: misc.c Проект: bminor/bash
/* 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);
}  
Пример #14
0
readline_constructor_impl::impl::impl(
  readline* parent,
  boost::asio::io_service& io_service,
  boost::function<void(std::string const&, readline&)> const& command_handler,
  boost::function<void(readline&)> const& eof_handler,
  std::string const& prompt,
  boost::filesystem::path const& history_file,
  boost::function<bool(std::string const&)> const& history_filter
) :
  parent_(parent),
  io_service_(io_service),
  command_handler_(command_handler),
  eof_handler_(eof_handler),
  prompt_(prompt),
  history_file_(history_file),
  history_filter_(history_filter),
  stdin_reader_(io_service, 0), // Bind to stdin
  redisplay_timer_(io_service)
{
  if (current_readline) {
    throw std::logic_error("Can't create multiple relasio::readline objects");
  }
  current_readline = this;
  if (!history_file_.empty() && boost::filesystem::exists(history_file_)) {
    if (!boost::filesystem::is_directory(history_file_)) {
      if (0 == read_history(history_file_.c_str())) {
        if (0 == history_set_pos(history_length)) {
          throw relasio_error("error setting history position\n");
        }
        if (history_length > 0) {
          // Set up last_line_
          HIST_ENTRY* last = history_get(history_length);
          if (last) last_line_ = last->line;
        }
      } else {
        throw relasio_error("error reading history\n");
      }
    }
  }
  rl_callback_handler_install(
    prompt_.c_str(), relasio_line_callback_handler
  );
  wait_for_chars();
}
Пример #15
0
int shell(void)
{
	fd_set readset;
	FD_ZERO(&g_context.readsave);

	if(g_verbose)
	{
		fprintf(stderr, "Opening connection to %s port %d\n", g_context.args.ip, g_context.args.port);
	}

	if((g_context.sock = connect_to(g_context.args.ip, g_context.args.port)) < 0)
	{
		return 1;
	}

	if(g_context.args.notty == 0)
	{
		if((g_context.outsock = connect_to(g_context.args.ip, g_context.args.port+2)) < 0)
		{
			fprintf(stderr, "Could not connect to stdout channel\n");
		}
		if((g_context.errsock = connect_to(g_context.args.ip, g_context.args.port+3)) < 0)
		{
			fprintf(stderr, "Could not connect to stderr channel\n");
		}
	}

	/*
	if((g_context.fssock == connect_to(g_context.args.ip, g_context.args.port+8)) < 0)
	{
		fprintf(stderr, "Could not connect to fs admin channel\n");
	}
	*/

	if(!g_context.args.script)
	{
		init_readline();
		read_history(g_context.history_file);
		history_set_pos(history_length);

		FD_SET(STDIN_FILENO, &g_context.readsave);
	}

	/* Change to the current directory, should return our path */
	execute_line("cd .");

	while(!g_context.exit)
	{
		int ret;

		readset = g_context.readsave;
		ret = select(FD_SETSIZE, &readset, NULL, NULL, NULL);
		if(ret < 0)
		{
			if(errno == EINTR)
			{
				continue;
			}

			perror("select");
			break;
		}
		else if(ret == 0)
		{
			continue;
		}
		else
		{
			if(!g_context.args.script)
			{
				if(FD_ISSET(STDIN_FILENO, &readset))
				{
					rl_callback_read_char();
				}
			}

			if(FD_ISSET(g_context.sock, &readset))
			{
				/* Do read */
				if(read_socket(g_context.sock) < 0)
				{
					close(g_context.sock);
					g_context.sock = -1;
					break;
				}
			}

			if((g_context.outsock >= 0) && FD_ISSET(g_context.outsock, &readset))
			{
				if(read_outsocket(g_context.outsock) < 0)
				{
					FD_CLR(g_context.outsock, &g_context.readsave);
					close(g_context.outsock);
					g_context.outsock = -1;
				}
			}
			if((g_context.errsock >= 0) && FD_ISSET(g_context.errsock, &readset))
			{
				if(read_errsocket(g_context.errsock) < 0)
				{
					FD_CLR(g_context.errsock, &g_context.readsave);
					close(g_context.errsock);
					g_context.errsock = -1;
				}
			}

			if((g_context.fssock >= 0) && FD_ISSET(g_context.fssock, &readset))
			{
				if(read_fssocket(g_context.fssock) < 0)
				{
					FD_CLR(g_context.fssock, &g_context.readsave);
					close(g_context.fssock);
					g_context.fssock = -1;
				}
			}
					
		}
	}

	if(!g_context.args.script)
	{
		write_history(g_context.history_file);
		rl_callback_handler_remove();
	}

	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 */
}
Пример #17
0
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;
}
Пример #18
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;
  static int piped_input_finished = FALSE;

  if (piped_input_finished) {
	  return NULL;
  }
  
  _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)) {
		/* Check we're possibly piped from another program. */
		BOOL ret;
		char *pos, buf[8192];
		DWORD to_read = sizeof(buf);

		/* Can't guarantee Unicode here, we don't control the data passed through the pipe. */
		pos = buf;
		memset(pos, 0, sizeof(buf));

		do {
			ret = ReadFile(_el_h_in, pos, to_read, &count, 0);
			pos += count;
			to_read -= count;
		} while (ret && to_read > 0);

		if (pos == buf) {
			_el_clean_exit();
			return NULL;
		} else if (to_read > 0) {
			/* Tried to fill the buf, but there's nothing anymore. Force finish. */
			piped_input_finished = TRUE;
		}

		buf[pos - buf] = '\0';
		ret_string = _strdup(buf);

		_el_clean_exit();

		return ret_string;
    }
    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");
  history_set_pos(history_length());
  /*
  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;
}
Пример #19
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 */
}
Пример #20
0
void history_adjust_pos(history *hist, int adjustment)
{
    if(!hist) return;

    history_set_pos(hist, hist->_history_index + adjustment);
}