Esempio n. 1
0
File: main.c Progetto: albfan/rlwrap
/*
 * create pty pair and fork using my_pty_fork; parent returns immediately; child
 * executes the part of rlwrap's command line that remains after
 * read_options_and_command_name() has harvested rlwrap's own options
 */  
static void
fork_child(char *command_name, char **argv)
{
  char *arg = argv[optind], *p, **argp;
  int pid;

  command_line = mysavestring(arg);
  for (argp = argv + optind + 1; *argp; argp++) {
    command_line = append_and_free_old (command_line, " ");
    command_line = append_and_free_old (command_line, *argp);
  }

  pid = my_pty_fork(&master_pty_fd, &saved_terminal_settings, &winsize);
  if (pid > 0)			/* parent: */
    return;
  else {			/* child: */
    DPRINTF1(DEBUG_TERMIO, "preparing to execute %s", arg);
    close_open_files_without_writing_buffers();
    
    if (client_term_name)
      mysetenv("TERM", client_term_name);   
    if (execvp(argv[optind], &argv[optind]) < 0) {
      if (last_opt > 0 && last_option_didnt_have_optional_argument) { /* e.g. 'rlwrap -a Password: sqlpus' will try to exec 'Password:'******'; !(){}"; *p; p++) /* does arg need shell quoting? */ 
	  if (strchr(arg,*p)) { 
            arg = add3strings("'", arg,"'"); /* quote it  */
            break;
	  }	
	fprintf(stderr, "Did you mean '%s' to be an option argument?\nThen you should write -%c%s, without the space(s)\n",
                argv[optind], last_opt, arg); 
      }
      myerror("Cannot execute %s", argv[optind]);   	/* stillborn child, parent will live on and display child's last gasps */
    }
  }
}
Esempio n. 2
0
char *
colour_name_to_ansi_code(const char *colour_name) {
  if (colour_name  && *colour_name && isalpha(*colour_name)) {
    char *lc_colour_name = mysavestring(lowercase(colour_name));
    char *bold_code = (isupper(*colour_name) ? "1" : "0");

#define isit(c) (strcmp(c,lc_colour_name)==0)
    char *colour_code =
      isit("black")   ? "30" :
      isit("red")     ? "31" :
      isit("green")   ? "32" :
      isit("yellow")  ? "33" :
      isit("blue")    ? "34" :
      isit("magenta") ? "35" :
      isit("purple")  ? "35" :
      isit("cyan")    ? "36" :
      isit("white")   ? "37" :
      NULL ;
      
#undef isit
    if (colour_code)
      return add3strings(bold_code,";",colour_code);
    else
      myerror("unrecognised colour name '%s'. Use e.g. 'yellow' or 'Blue'.", colour_name);
  }
  return mysavestring(colour_name);
}       
Esempio n. 3
0
void
initialise_colour_codes(char *colour)
{
  int attributes, foreground, background;
  DPRINTF1(DEBUG_READLINE, "initialise_colour_codes(\"%s\")", colour);
  attributes = foreground = -1;
  background = 40; /* don't need to specify background; 40 passes the test automatically */
  sscanf(colour, "%d;%d;%d", &attributes, &foreground, &background);
  
#define OUTSIDE(lo,hi,val) (val < lo || val > hi) 
  if (OUTSIDE(0,8,attributes) || OUTSIDE(30,37,foreground) || OUTSIDE(40,47,background))
    myerror(FATAL|NOERRNO, "\n"
            "  prompt colour spec should be <attr>;<fg>[;<bg>]\n"
            "  where <attr> ranges over [0...8], <fg> over [30...37] and <bg> over [40...47]\n"
            "  example: 0;33 for yellow on current background, 1;31;40 for bold red on black ");
  colour_start= add3strings("\033[", colour,"m");
  colour_end  = "\033[0m";
}
Esempio n. 4
0
/* returns a colourised copy of prompt, trailing space is not colourised */
char*
colourise (const char *prompt)
{
  char *prompt_copy, *trailing_space, *colour_end_with_space, *result, *p;
  prompt_copy = mysavestring(prompt);
  if (strchr(prompt_copy, '\033') || strchr(prompt_copy, RL_PROMPT_START_IGNORE) ) {     /* prompt contains escape codes? */
    DPRINTF1(DEBUG_READLINE, "colourise %s: left as-is", prompt);
    return prompt_copy; /* if so, leave prompt alone  */
  }
  for (p = prompt_copy + strlen(prompt_copy); p > prompt_copy && *(p-1) == ' '; p--)
    ; /* skip back over trailing space */
  trailing_space = mysavestring(p); /* p now points at first trailing space, or else the final NULL */
  *p = '\0';
  colour_end_with_space = add2strings(colour_end, trailing_space);
  result = add3strings(colour_start, prompt_copy, colour_end_with_space);
  free (prompt_copy); free(trailing_space); free(colour_end_with_space);
  DPRINTF1(DEBUG_READLINE, "colourise %s: colour added ", prompt);
  return result;
}
Esempio n. 5
0
static void
munge_file_in_editor(const char *filename, int lineno, int colno)
{

  int ret;
  char *editor_command1, *editor_command2, *editor_command3,
       *editor_command4, *line_number_as_string, *column_number_as_string,  **possible_editor_commands;

  /* find out which editor command we have to use */
  possible_editor_commands = list4(getenv("RLWRAP_EDITOR"), getenv("EDITOR"), getenv("VISUAL"), "vi +%L");
  editor_command1 = first_of(possible_editor_commands);
  line_number_as_string = as_string(lineno);
  column_number_as_string = as_string(colno);
  editor_command2 = search_and_replace("%L", line_number_as_string, editor_command1, 0, NULL, NULL);
  editor_command3 = search_and_replace("%C", column_number_as_string, editor_command2, 0, NULL, NULL);
  editor_command4 = strstr(editor_command3, "%F") ?
    search_and_replace("%F", filename, editor_command3, 0, NULL, NULL) :
    add3strings(editor_command3, " ", filename);
  

  /* call editor, temporarily restoring terminal settings */    
  if (terminal_settings_saved && (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_terminal_settings) < 0))    /* reset terminal */
    myerror(FATAL|USE_ERRNO, "tcsetattr error on stdin");
  DPRINTF1(DEBUG_READLINE, "calling %s", editor_command4);
  if ((ret = system(editor_command4))) {
    if (WIFSIGNALED(ret)) {
      fprintf(stderr, "\n"); 
      myerror(FATAL|NOERRNO, "editor killed by signal");
    } else {    
      myerror(FATAL|USE_ERRNO, "failed to invoke editor with '%s'", editor_command4);
    }
  }
  completely_mirror_slaves_terminal_settings();
  ignore_queued_input = TRUE;  

  free_multiple(possible_editor_commands, editor_command2, editor_command3,
                editor_command4, line_number_as_string, column_number_as_string, FMEND);
}
Esempio n. 6
0
void spawn_filter(const char *filter_command) {
    int input_pipe_fds[2];
    int output_pipe_fds[2];

    mypipe(input_pipe_fds);
    filter_input_fd = input_pipe_fds[1]; /* rlwrap writes filter input to this */

    mypipe(output_pipe_fds);
    filter_output_fd = output_pipe_fds[0]; /* rlwrap  reads filter output from here */
    DPRINTF1(DEBUG_FILTERING, "preparing to spawn filter <%s>", filter_command);
    assert(!command_pid || signal_handlers_were_installed);  /* if there is a command, then signal handlers are installed */

    if ((filter_pid = fork()) < 0)
        myerror(FATAL|USE_ERRNO, "Cannot spawn filter '%s'", filter_command);
    else if (filter_pid == 0) {           /* child */
        int signals_to_allow[] = {SIGPIPE, SIGCHLD, SIGALRM, SIGUSR1, SIGUSR2};
        char **argv;
        unblock_signals(signals_to_allow);  /* when we run a pager from a filter we want to catch these */


        DEBUG_RANDOM_SLEEP;
        i_am_child =  TRUE;
        /* set environment for filter (it needs to know at least the file descriptors for its input and output) */

        if (!getenv("RLWRAP_FILTERDIR"))
            mysetenv("RLWRAP_FILTERDIR", add2strings(DATADIR,"/rlwrap/filters"));
        mysetenv("PATH", add3strings(getenv("RLWRAP_FILTERDIR"),":",getenv("PATH")));
        mysetenv("RLWRAP_VERSION", VERSION);
        mysetenv("RLWRAP_COMMAND_PID",  as_string(command_pid));
        mysetenv("RLWRAP_COMMAND_LINE", command_line);
        if (impatient_prompt)
            mysetenv("RLWRAP_IMPATIENT", "1");
        mysetenv("RLWRAP_INPUT_PIPE_FD", as_string(input_pipe_fds[0]));
        mysetenv("RLWRAP_OUTPUT_PIPE_FD", as_string(output_pipe_fds[1]));
        mysetenv("RLWRAP_MASTER_PTY_FD", as_string(master_pty_fd));

        close(filter_input_fd);
        close(filter_output_fd);


        if (scan_metacharacters(filter_command, "'|\"><"))  { /* if filter_command contains shell metacharacters, let the shell unglue them */
            char *exec_command = add3strings("exec", " ", filter_command);
            argv = list4("sh", "-c", exec_command, NULL);
        } else {                                              /* if not, split and feed to execvp directly (cheaper, better error message) */
            argv = split_with(filter_command, " ");
        }
        assert(argv[0]);
        if(execvp(argv[0], argv) < 0) {
            char *sorry = add3strings("Cannot exec filter '", argv[0], add2strings("': ", strerror(errno)));
            write_message(output_pipe_fds[1], TAG_ERROR, sorry, "to stdout"); /* this will kill rlwrap */
            mymicrosleep(100 * 1000); /* 100 sec for rlwrap to go away should be enough */
            exit (-1);
        }
        assert(!"not reached");

    } else {
        DEBUG_RANDOM_SLEEP;
        signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE - we have othere ways to deal with filter death */
        DPRINTF1(DEBUG_FILTERING, "spawned filter with pid %d", filter_pid);
        close (input_pipe_fds[0]);
        close (output_pipe_fds[1]);
    }
}
Esempio n. 7
0
static int
munge_line_in_editor(int count, int key)
{
  int line_number = 0, column_number = 0, tmpfile_OK, ret, tmpfile_fd, bytes_read;
  size_t tmpfilesize;
  char *p, *tmpdir, *tmpfilename, *text_to_edit;
  char *editor_command1, *editor_command2, *editor_command3, *editor_command4,
    *line_number_as_string, *column_number_as_string;
  char *input, *rewritten_input, *rewritten_input2, **possible_tmpdirs, **possible_editor_commands;


  if (!multiline_separator)
    return 0;

  possible_tmpdirs = list4(getenv("TMPDIR"), getenv("TMP"), getenv("TEMP"), "/tmp");
  possible_editor_commands = list4(getenv("RLWRAP_EDITOR"), getenv("EDITOR"), getenv("VISUAL"), "vi +%L");

  /* create temporary filename */
#ifdef HAVE_MKSTEMP
  tmpdir = first_of(possible_tmpdirs);
  tmpfilename = add3strings(tmpdir, "/rlwrap_", "XXXXXX");
  tmpfile_OK = mkstemp(tmpfilename);
#else
  tmpfilename = mymalloc(L_tmpnam);
  tmpfile_OK = (int)tmpnam(tmpfilename); /* manpage says: Never use this function. Use mkstemp(3) instead */
#endif
  if (!tmpfile_OK)
    myerror("could not find unique temporary file name");

  /* write current input to it, replacing the newline substitute (multiline_separator) with the real thing */
  tmpfile_fd = open(tmpfilename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
  if (tmpfile_fd < 0)
    myerror("could not create temporary file %s", tmpfilename);
  text_to_edit =
    search_and_replace(multiline_separator, "\n", rl_line_buffer, rl_point,
                       &line_number, &column_number);
  write_patiently(tmpfile_fd, text_to_edit, strlen(text_to_edit), "to temporary file");

  if (close(tmpfile_fd) != 0) /* improbable */
    myerror("couldn't close temporary file %s", tmpfilename); 

  /* find out which editor command we have to use */

  editor_command1 = first_of(possible_editor_commands);
  line_number_as_string = as_string(line_number);
  column_number_as_string = as_string(column_number);
  editor_command2 =
    search_and_replace("%L", line_number_as_string, editor_command1, 0, NULL,
                       NULL);
  editor_command3 =
    search_and_replace("%C", column_number_as_string, editor_command2, 0,
                       NULL, NULL);
  editor_command4 = add3strings(editor_command3, " ", tmpfilename);

  
  
  

  /* call editor, temporarily restoring terminal settings */    
  if (terminal_settings_saved && (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_terminal_settings) < 0))    /* reset terminal */
    myerror("tcsetattr error on stdin");
  DPRINTF1(DEBUG_READLINE, "calling %s", editor_command4);
  if ((ret = system(editor_command4))) {
    if (WIFSIGNALED(ret)) {
      fprintf(stderr, "\n"); errno = 0;
      myerror("editor killed by signal");
    } else {    
      myerror("failed to invoke editor with '%s'", editor_command4);
    }
  }
  completely_mirror_slaves_terminal_settings();
  ignore_queued_input = TRUE;  

  /* read back edited input, replacing real newline with substitute */
  tmpfile_fd = open(tmpfilename, O_RDONLY);
  if (tmpfile_fd < 0)
    myerror("could not read temp file %s", tmpfilename);
  tmpfilesize = filesize(tmpfilename);
  input = mymalloc(tmpfilesize + 1);
  bytes_read = read(tmpfile_fd, input, tmpfilesize);
  if (bytes_read < 0)
    myerror("unreadable temp file %s", tmpfilename);
  input[bytes_read] = '\0';
  rewritten_input = search_and_replace("\t", "    ", input, 0, NULL, NULL);     /* rlwrap cannot handle tabs in input lines */
  rewritten_input2 =
    search_and_replace("\n", multiline_separator, rewritten_input, 0, NULL,
                       NULL);
  for(p = rewritten_input2; *p ;p++)
    if(*p < ' ')
      *p = ' ';        /* replace all control characters (like \r) by spaces */


  rl_delete_text(0, strlen(rl_line_buffer));
  rl_point = 0;  
  clear_line();
  cr();
  my_putstr(saved_rl_state.cooked_prompt);
  rl_insert_text(rewritten_input2);
  rl_point = 0;                 /* leave cursor on predictable place */
  rl_done = 1;                  /* accept line immediately */

  


  /* wash those dishes */
  if (unlink(tmpfilename))
    myerror("could not delete temporary file %s", tmpfilename);
  free(editor_command2);
  free(editor_command3);
  free(editor_command4);
  free(line_number_as_string);
  free(column_number_as_string);
  free(tmpfilename);
  free(text_to_edit);
  free(input);
  free(rewritten_input);
  free(rewritten_input2);
  
  return_key = (char)'\n';
  return 0;
}
Esempio n. 8
0
File: main.c Progetto: albfan/rlwrap
char *
read_options_and_command_name(int argc, char **argv)
{
  int c;
  char *opt_C = NULL;
  int option_count = 0;
  int opt_b = FALSE;
  int opt_f = FALSE;
  int remaining = -1; /* remaining number of arguments on command line */
  int longindex = -1; /* index of current option in longopts[], set by getopt_long */
  
  
  full_program_name = mysavestring(argv[0]);
  program_name = mybasename(full_program_name);	/* normally "rlwrap"; needed by myerror() */
  rl_basic_word_break_characters = " \t\n\r(){}[],+-=&^%$#@\";|\\";

  opterr = 0;			/* we do our own error reporting */

  while (1) {
#ifdef HAVE_GETOPT_LONG
    c = getopt_long(argc, argv, optstring, longopts, &longindex);
#else
    c = getopt(argc, argv, optstring);
#endif

    if (c == EOF)
      break;
    option_count++;
    last_option_didnt_have_optional_argument = FALSE;
    remaining = argc - optind;
    last_opt = c;    

    switch (c) {
    case 'a':
      always_readline = TRUE;
      if (check_optarg('a', remaining))
        password_prompt_search_string = mysavestring(optarg);
      break;
    case 'A':	ansi_colour_aware = TRUE; break;
    case 'b':
      rl_basic_word_break_characters = add3strings("\r\n \t", optarg, "");
      opt_b = TRUE;
      break;
    case 'c':	complete_filenames = TRUE; break;
    case 'C':	opt_C = mysavestring(optarg); break;
    case 'd':
#ifdef DEBUG
      if (option_count > 1)
        myerror("-d or --debug option has to be the *first* rlwrap option");
      if (check_optarg('d', remaining))
        debug = atoi(optarg);
      else
        debug = DEBUG_DEFAULT;
#else
      myerror
        ("To use -d( for debugging), configure %s with --enable-debug and rebuild",
         program_name);
#endif
      break;

    case 'D': 
      history_duplicate_avoidance_policy=atoi(optarg);
      if (history_duplicate_avoidance_policy < 0 || history_duplicate_avoidance_policy > 2)
        myerror("%s option with illegal value %d, should be 0, 1 or 2",
                current_option('D', longindex), history_duplicate_avoidance_policy);
      break;
    case 'f':
      if (strncmp(optarg, ".", 10) == 0)
        feed_history_into_completion_list =  TRUE;
      else
        feed_file_into_completion_list(optarg);
      opt_f = TRUE;
      break;
    case 'F': myerror("The -F (--history-format) option is obsolete. Use -z \"history_format '%s'\" instead", optarg);
    case 'g': forget_regexp = mysavestring(optarg); match_regexp("just testing", forget_regexp, 1); break;
    case 'h':	usage(EXIT_SUCCESS);		/* will call exit() */
    case 'H':	history_filename = mysavestring(optarg); break;
    case 'i': 
      if (opt_f)
        myerror("-i option has to precede -f options");
      completion_is_case_sensitive = FALSE;
      break;
    case 'I':	pass_on_sigINT_as_sigTERM = TRUE; break;
    case 'l':	open_logfile(optarg); break;
    case 'n':	nowarn = TRUE; break;
    case 'm':
#ifndef HAVE_SYSTEM
      mywarn("the -m option doesn't work on this system");
#endif
      multiline_separator =
        (check_optarg('m', remaining) ? mysavestring(optarg) : " \\ ");
      break;
    case 'N': commands_children_not_wrapped = TRUE; break;
    case 'o': 
      one_shot_rlwrap = TRUE;
      impatient_prompt = FALSE;
      wait_before_prompt = 200;
      break;
    case 'O': prompt_regexp = mysavestring(optarg); match_regexp("just testing", prompt_regexp, 1); break;
    case 'p':
      colour_the_prompt = TRUE;
      initialise_colour_codes(check_optarg('p', remaining) ?
                              colour_name_to_ansi_code(optarg) :
                              colour_name_to_ansi_code("Red"));
      break;
    case 'P':
      pre_given = mysavestring(optarg);
      always_readline = TRUE; /* pre_given does not work well with transparent mode */
	
      break;
    case 'q': rl_basic_quote_characters = mysavestring(optarg); break;
    case 'r':	remember_for_completion = TRUE;	break;
    case 'R': renice = TRUE;	break;
    case 's':
      histsize = atoi(optarg);
      if (histsize < 0) {
        write_histfile = 0;
        histsize = -histsize;
      }
      break;
    case 'S': substitute_prompt =  mysavestring(optarg);break;
    case 't':	client_term_name=mysavestring(optarg);break;
#ifdef DEBUG
    case 'T':	test_terminal(); exit(EXIT_SUCCESS);
#endif
    case 'v':	printf("rlwrap %s\n",  VERSION); exit(EXIT_SUCCESS);
    case 'w':
      wait_before_prompt = atoi(optarg);
      if (wait_before_prompt < 0) {
        wait_before_prompt *= -1;
        impatient_prompt =  FALSE;
      }
      break;
    case 'z': filter_command = mysavestring(optarg);	break;
    case '?':
      assert(optind > 0);
      myerror("unrecognised option %s\ntry '%s --help' for more information",
              argv[optind-1], full_program_name);
    case ':':
      assert(optind > 0);
      myerror
        ("option %s requires an argument \ntry '%s --help' for more information",
         argv[optind-1], full_program_name);

    default:
      usage(EXIT_FAILURE);
    }
  }

  if (!complete_filenames && !opt_b) {	/* use / and . as default breaking characters whenever we don't complete filenames */
    rl_basic_word_break_characters =
      add2strings(rl_basic_word_break_characters, "/.");
  }

  
  if (optind >= argc) { /* rlwrap -a -b -c with no command specified */
    if (filter_command) { /* rlwrap -z filter with no command specified */
      mysignal(SIGALRM, &handle_sigALRM); /* needed for read_patiently2 */
      spawn_filter(filter_command);
      pass_through_filter(TAG_OUTPUT,""); /* ignore result but allow TAG_OUTPUT_OUT_OF_BAND */
      cleanup_rlwrap_and_exit(EXIT_SUCCESS);
    } else {
      usage(EXIT_FAILURE); 
    }
  }
  if (opt_C) {
    int countback = atoi(opt_C);	/* investigate whether -C option argument is numeric */

    if (countback > 0) {	/* e.g -C 1 or -C 12 */
      if (argc - countback < optind)	/* -C 666 */
	myerror("when using -C %d you need at least %d non-option arguments",
		countback, countback);
      else if (argv[argc - countback][0] == '-')	/* -C 2 perl -d blah.pl */
	myerror("the last argument minus %d appears to be an option!",
		countback);
      else {			/* -C 1 perl test.cgi */
	command_name = mysavestring(mybasename(argv[argc - countback]));

      }
    } else if (countback == 0) {	/* -C name1 name2 or -C 0 */
      if (opt_C[0] == '0' && opt_C[1] == '\0')	/* -C 0 */
	myerror("-C 0 makes no sense");
      else if (strlen(mybasename(opt_C)) != strlen(opt_C))	/* -C dir/name */
	myerror("-C option argument should not contain directory components");
      else if (opt_C[0] == '-')	/* -C -d  (?) */
	myerror("-C option needs argument");
      else			/* -C name */
	command_name = opt_C;
    } else {			/* -C -2 */
      myerror
	("-C option needs string or positive number as argument, perhaps you meant -C %d?",
	 -countback);
    }
  } else {			/* no -C option given, use command name */
    command_name = mysavestring(mybasename(argv[optind]));
  }
  assert(command_name != NULL);
  return command_name;
}
Esempio n. 9
0
File: main.c Progetto: albfan/rlwrap
/* Read history and completion word lists */
void
init_rlwrap()
{

  char *homedir, *histdir, *homedir_prefix, *hostname;
  time_t now;
  
  /* open debug file if necessary */

  if (debug) {    
    debug_fp = fopen(DEBUG_FILENAME, "w");
    if (!debug_fp)
      myerror("Couldn't open debug file %s", DEBUG_FILENAME);
    setbuf(debug_fp, NULL); /* always write debug messages to disk at once */
  }
  hostname = getenv("HOSTNAME") ? getenv("HOSTNAME") : "?";
  now = time(NULL);
  DPRINTF0(DEBUG_ALL, "-*- mode: grep -*-");
  DPRINTF3(DEBUG_ALL, "rlwrap version %s, host: %s, time: %s", VERSION, hostname, ctime(&now));
  init_terminal();

  
  
  /* Determine rlwrap home dir and prefix for default history and completion filenames */
  homedir = (getenv("RLWRAP_HOME") ? getenv("RLWRAP_HOME") : getenv("HOME"));
  homedir_prefix = (getenv("RLWRAP_HOME") ?                    /* is RLWRAP_HOME set?                */
		    add2strings(getenv("RLWRAP_HOME"), "/") :  /* use $RLWRAP_HOME/<command>_history */
		    add2strings(getenv("HOME"), "/."));	       /* if not, use ~/.<command>_history   */

  /* Determine history file name and check its existence and permissions */

  if (history_filename) {
    histdir = mydirname(history_filename);
  } else {
    histdir = homedir;
    history_filename = add3strings(homedir_prefix, command_name, "_history");
  }
  
  if (write_histfile) {
    if (access(history_filename, F_OK) == 0) {	/* already exists, can we read/write it? */
      if (access(history_filename, R_OK | W_OK) != 0) {
	myerror("cannot read and write %s", history_filename);
      }
    } else {			        /* doesn't exist, can we create it? */
      if(access(histdir, W_OK) != 0) {
        if (errno == ENOENT) {
          mode_t oldmask = umask(0);
          if (mkdir(histdir, 0700))       /* rwx------ */
            myerror("cannot create directory %s", histdir);
          umask(oldmask);
        } else {
          myerror("cannot create history file in %s", histdir);
        }
      }
    }
  } else {			/* ! write_histfile */
    if (access(history_filename, R_OK) != 0) {
      myerror("cannot read %s", history_filename);
    }
  }

  /* Initialize history */
  using_history();
  stifle_history(histsize);
  read_history(history_filename);	/* ignore errors here: history file may not yet exist, but will be created on exit */

  if (feed_history_into_completion_list)
    feed_file_into_completion_list(history_filename);
  /* Determine completion file name (completion files are never written to,
     and ignored when unreadable or non-existent) */

  completion_filename =
    add3strings(homedir_prefix, command_name, "_completions");
  default_completion_filename =
    add3strings(DATADIR, "/rlwrap/completions/", command_name);

  rl_readline_name = command_name;

  /* Initialise completion list (if <completion_filename> is readable) */
  if (access(completion_filename, R_OK) == 0) {
    feed_file_into_completion_list(completion_filename);
  } else if (access(default_completion_filename, R_OK) == 0) {
    feed_file_into_completion_list(default_completion_filename);
  }

  
}
Esempio n. 10
0
static int
munge_line_in_editor(int count, int key)
{
  int line_number = 0, column_number = 0,  ret, tmpfile_fd, bytes_read;
  size_t tmpfilesize;
  char *p, *tmpfilename, *text_to_edit;
  char *editor_command1, *editor_command2, *editor_command3, *editor_command4,
    *line_number_as_string, *column_number_as_string;
  char *input, *rewritten_input, *rewritten_input2,  **possible_editor_commands;


  if (!multiline_separator)
    return 0;

  tmpfile_fd = open_unique_tempfile(multi_line_tmpfile_ext, &tmpfilename);

  text_to_edit =
    search_and_replace(multiline_separator, "\n", rl_line_buffer, rl_point,
                       &line_number, &column_number);
  write_patiently(tmpfile_fd, text_to_edit, strlen(text_to_edit), "to temporary file");

  if (close(tmpfile_fd) != 0) /* improbable */
    myerror(FATAL|USE_ERRNO, "couldn't close temporary file %s", tmpfilename); 

  /* find out which editor command we have to use */
  possible_editor_commands = list4(getenv("RLWRAP_EDITOR"), getenv("EDITOR"), getenv("VISUAL"), "vi +%L");
  editor_command1 = first_of(possible_editor_commands);
  line_number_as_string = as_string(line_number);
  column_number_as_string = as_string(column_number);
  editor_command2 =
    search_and_replace("%L", line_number_as_string, editor_command1, 0, NULL,
                       NULL);
  editor_command3 =
    search_and_replace("%C", column_number_as_string, editor_command2, 0,
                       NULL, NULL);
  editor_command4 = add3strings(editor_command3, " ", tmpfilename);
  

  /* call editor, temporarily restoring terminal settings */    
  if (terminal_settings_saved && (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_terminal_settings) < 0))    /* reset terminal */
    myerror(FATAL|USE_ERRNO, "tcsetattr error on stdin");
  DPRINTF1(DEBUG_READLINE, "calling %s", editor_command4);
  if ((ret = system(editor_command4))) {
    if (WIFSIGNALED(ret)) {
      fprintf(stderr, "\n"); 
      myerror(FATAL|NOERRNO, "editor killed by signal");
    } else {    
      myerror(FATAL|USE_ERRNO, "failed to invoke editor with '%s'", editor_command4);
    }
  }
  completely_mirror_slaves_terminal_settings();
  ignore_queued_input = TRUE;  

  /* read back edited input, replacing real newline with substitute */
  tmpfile_fd = open(tmpfilename, O_RDONLY);
  if (tmpfile_fd < 0)
    myerror(FATAL|USE_ERRNO, "could not read temp file %s", tmpfilename);
  tmpfilesize = filesize(tmpfilename);
  input = mymalloc(tmpfilesize + 1);
  bytes_read = read(tmpfile_fd, input, tmpfilesize);
  if (bytes_read < 0)
    myerror(FATAL|USE_ERRNO, "unreadable temp file %s", tmpfilename);
  input[bytes_read] = '\0';
  rewritten_input = search_and_replace("\t", "    ", input, 0, NULL, NULL);     /* rlwrap cannot handle tabs in input lines */
  rewritten_input2 =
    search_and_replace("\n", multiline_separator, rewritten_input, 0, NULL, NULL);
  for(p = rewritten_input2; *p ;p++)
    if(*p >= 0 && *p < ' ') /* @@@FIXME: works for UTF8, but not UTF16 or UTF32 (Mention this in manpage?)*/ 
      *p = ' ';        /* replace all control characters (like \r) by spaces */


  rl_delete_text(0, strlen(rl_line_buffer));
  rl_point = 0;  
  clear_line();
  cr();
  my_putstr(saved_rl_state.cooked_prompt);
  rl_insert_text(rewritten_input2);
  rl_point = 0;                 /* leave cursor on predictable place */
  rl_done = 1;                  /* accept line immediately */

  


  /* wash those dishes */
  if (unlink(tmpfilename))
    myerror(FATAL|USE_ERRNO, "could not delete temporary file %s", tmpfilename);
  free(editor_command2);
  free(editor_command3);
  free(editor_command4);
  free(line_number_as_string);
  free(column_number_as_string);
  free(tmpfilename);
  free(text_to_edit);
  free(input);
  free(rewritten_input);
  free(rewritten_input2);
  
  return_key = (char)'\n';
  return 0;
}