예제 #1
0
파일: sig.c 프로젝트: DavidMulder/heimdal
/* sig_init():
 *	Initialize all signal stuff
 */
libedit_private int
sig_init(EditLine *el)
{
	size_t i;
	sigset_t *nset, oset;

	el->el_signal = el_malloc(sizeof(*el->el_signal));
	if (el->el_signal == NULL)
		return -1;

	nset = &el->el_signal->sig_set;
	(void) sigemptyset(nset);
#define	_DO(a) (void) sigaddset(nset, a);
	ALLSIGS
#undef	_DO
	(void) sigprocmask(SIG_BLOCK, nset, &oset);

	for (i = 0; sighdl[i] != -1; i++) {
		el->el_signal->sig_action[i].sa_handler = SIG_ERR;
		el->el_signal->sig_action[i].sa_flags = 0;
		sigemptyset(&el->el_signal->sig_action[i].sa_mask);
	}

	(void) sigprocmask(SIG_SETMASK, &oset, NULL);

	return 0;
}
예제 #2
0
파일: read.c 프로젝트: jabedude/netbsd-src
/* read_init():
 *	Initialize the read stuff
 */
libedit_private int
read_init(EditLine *el)
{
	if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL)
		return -1;
	/* builtin read_char */
	el->el_read->read_char = read_char;
	return 0;
}
예제 #3
0
파일: hist.c 프로젝트: Belgarion/rkom
/* hist_init():
 *	Initialization function.
 */
protected int
hist_init(EditLine *el)
{

	el->el_history.fun = NULL;
	el->el_history.ref = NULL;
	el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
	el->el_history.last = el->el_history.buf;
	return (0);
}
예제 #4
0
파일: read.c 프로젝트: programble/dotfiles
/* read_init():
 *	Initialize the read stuff
 */
libedit_private int
read_init(EditLine *el)
{
	struct macros *ma;

	if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL)
		return -1;

	ma = &el->el_read->macros;
	if ((ma->macro = el_malloc(EL_MAXMACRO *
	    sizeof(*ma->macro))) == NULL) {
		free(el->el_read);
		return -1;
	}
	ma->level = -1;
	ma->offset = 0;

	/* builtin read_char */
	el->el_read->read_char = read_char;
	return 0;
}
예제 #5
0
파일: hist.c 프로젝트: jabedude/netbsd-src
/* hist_init():
 *	Initialization function.
 */
libedit_private int
hist_init(EditLine *el)
{

	el->el_history.fun = NULL;
	el->el_history.ref = NULL;
	el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
	el->el_history.sz  = EL_BUFSIZ;
	if (el->el_history.buf == NULL)
		return -1;
	el->el_history.last = el->el_history.buf;
	return 0;
}
예제 #6
0
파일: search.c 프로젝트: petabi/pkgsrc
/* search_init():
 *	Initialize the search stuff
 */
protected int
search_init(EditLine *el)
{

	el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
	if (el->el_search.patbuf == NULL)
		return (-1);
	el->el_search.patlen = 0;
	el->el_search.patdir = -1;
	el->el_search.chacha = '\0';
	el->el_search.chadir = CHAR_FWD;
	el->el_search.chatflg = 0;
	return (0);
}
예제 #7
0
/* el_init():
 *	Initialize editline and set default parameters.
 */
public EditLine *
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{

	EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));

	if (el == NULL)
		return (NULL);

	memset(el, 0, sizeof(EditLine));

	el->el_infile = fin;
	el->el_outfile = fout;
	el->el_errfile = ferr;

	el->el_infd = fileno(fin);

	if ((el->el_prog = el_strdup(prog)) == NULL) {
		el_free(el);
		return NULL;
	}

	/*
         * Initialize all the modules. Order is important!!!
         */
	el->el_flags = 0;

	if (term_init(el) == -1) {
		el_free(el->el_prog);
		el_free(el);
		return NULL;
	}
	(void) key_init(el);
	(void) map_init(el);
	if (tty_init(el) == -1)
		el->el_flags |= NO_TTY;
	(void) ch_init(el);
	(void) search_init(el);
	(void) hist_init(el);
	(void) prompt_init(el);
	(void) sig_init(el);
	(void) read_init(el);

	return (el);
}
예제 #8
0
static wchar_t *
find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer,
    const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length)
{
	/* We now look backwards for the start of a filename/variable word */
	const wchar_t *ctemp = cursor;
	int cursor_at_quote;
	size_t len;
	wchar_t *temp;

	/* if the cursor is placed at a slash or a quote, we need to find the
	 * word before it
	 */
	if (ctemp > buffer) {
		switch (ctemp[-1]) {
		case '\\':
		case '\'':
		case '"':
			cursor_at_quote = 1;
			ctemp--;
			break;
		default:
			cursor_at_quote = 0;
		}
	} else
		cursor_at_quote = 0;

	while (ctemp > buffer
	    && !wcschr(word_break, ctemp[-1])
	    && (!special_prefixes || !wcschr(special_prefixes, ctemp[-1])))
		ctemp--;

	len = (size_t) (cursor - ctemp - cursor_at_quote);
	temp = el_malloc((len + 1) * sizeof(*temp));
	if (temp == NULL)
		return NULL;
	(void) wcsncpy(temp, ctemp, len);
	temp[len] = '\0';
	if (cursor_at_quote)
		len++;
	*length = len;
	return temp;
}
예제 #9
0
/*
 * does tilde expansion of strings of type ``~user/foo''
 * if ``user'' isn't valid user name or ``txt'' doesn't start
 * w/ '~', returns pointer to strdup()ed copy of ``txt''
 *
 * it's callers's responsibility to free() returned string
 */
char *
fn_tilde_expand(const char *txt)
{
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
	struct passwd pwres;
	char pwbuf[1024];
#endif
	struct passwd *pass;
	char *temp;
	size_t len = 0;

	if (txt[0] != '~')
		return strdup(txt);

	temp = strchr(txt + 1, '/');
	if (temp == NULL) {
		temp = strdup(txt + 1);
		if (temp == NULL)
			return NULL;
	} else {
		/* text until string after slash */
		len = (size_t)(temp - txt + 1);
		temp = el_malloc(len * sizeof(*temp));
		if (temp == NULL)
			return NULL;
		(void)strncpy(temp, txt + 1, len - 2);
		temp[len - 2] = '\0';
	}
	if (temp[0] == 0) {
#ifdef HAVE_GETPW_R_POSIX
 		if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf),
		    &pass) != 0)
 			pass = NULL;
#elif HAVE_GETPW_R_DRAFT
		pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
#else
		pass = getpwuid(getuid());
#endif
	} else {
#ifdef HAVE_GETPW_R_POSIX
		if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
			pass = NULL;
#elif HAVE_GETPW_R_DRAFT
		pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
#else
		pass = getpwnam(temp);
#endif
	}
	el_free(temp);		/* value no more needed */
	if (pass == NULL)
		return strdup(txt);

	/* update pointer txt to point at string immedially following */
	/* first slash */
	txt += len;

	len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
	temp = el_malloc(len * sizeof(*temp));
	if (temp == NULL)
		return NULL;
	(void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);

	return temp;
}
예제 #10
0
/*
 * Complete the word at or before point,
 * 'what_to_do' says what to do with the completion.
 * \t   means do standard completion.
 * `?' means list the possible completions.
 * `*' means insert all of the possible completions.
 * `!' means to do standard completion, and list all possible completions if
 * there is more than one.
 *
 * Note: '*' support is not implemented
 *       '!' could never be invoked
 */
int
fn_complete(EditLine *el,
	char *(*complet_func)(const char *, int),
	char **(*attempted_completion_function)(const char *, int, int),
	const Char *word_break, const Char *special_prefixes,
	const char *(*app_func)(const char *), size_t query_items,
	int *completion_type, int *over, int *point, int *end)
{
	const TYPE(LineInfo) *li;
	Char *temp;
        char **matches;
	const Char *ctemp;
	size_t len;
	int what_to_do = '\t';
	int retval = CC_NORM;

	if (el->el_state.lastcmd == el->el_state.thiscmd)
		what_to_do = '?';

	/* readline's rl_complete() has to be told what we did... */
	if (completion_type != NULL)
		*completion_type = what_to_do;

	if (!complet_func)
		complet_func = fn_filename_completion_function;
	if (!app_func)
		app_func = append_char_function;

	/* We now look backwards for the start of a filename/variable word */
	li = FUN(el,line)(el);
	ctemp = li->cursor;
	while (ctemp > li->buffer
	    && !Strchr(word_break, ctemp[-1])
	    && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
		ctemp--;

	len = (size_t)(li->cursor - ctemp);
	temp = el_malloc((len + 1) * sizeof(*temp));
	(void)Strncpy(temp, ctemp, len);
	temp[len] = '\0';

	/* these can be used by function called in completion_matches() */
	/* or (*attempted_completion_function)() */
	if (point != NULL)
		*point = (int)(li->cursor - li->buffer);
	if (end != NULL)
		*end = (int)(li->lastchar - li->buffer);

	if (attempted_completion_function) {
		int cur_off = (int)(li->cursor - li->buffer);
		matches = (*attempted_completion_function)(
		    ct_encode_string(temp, &el->el_scratch),
		    cur_off - (int)len, cur_off);
	} else
		matches = NULL;
	if (!attempted_completion_function || 
	    (over != NULL && !*over && !matches))
		matches = completion_matches(
		    ct_encode_string(temp, &el->el_scratch), complet_func);

	if (over != NULL)
		*over = 0;

	if (matches) {
		int i;
		size_t matches_num, maxlen, match_len, match_display=1;

		retval = CC_REFRESH;
		/*
		 * Only replace the completed string with common part of
		 * possible matches if there is possible completion.
		 */
		if (matches[0][0] != '\0') {
			el_deletestr(el, (int) len);
			FUN(el,insertstr)(el,
			    ct_decode_string(matches[0], &el->el_scratch));
		}

		if (what_to_do == '?')
			goto display_matches;

		if (matches[2] == NULL &&
		    (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) {
			/*
			 * We found exact match. Add a space after
			 * it, unless we do filename completion and the
			 * object is a directory.
			 */
			FUN(el,insertstr)(el,
			    ct_decode_string((*app_func)(matches[0]),
			    &el->el_scratch));
		} else if (what_to_do == '!') {
    display_matches:
			/*
			 * More than one match and requested to list possible
			 * matches.
			 */

			for(i = 1, maxlen = 0; matches[i]; i++) {
				match_len = strlen(matches[i]);
				if (match_len > maxlen)
					maxlen = match_len;
			}
			/* matches[1] through matches[i-1] are available */
			matches_num = (size_t)(i - 1);
				
			/* newline to get on next line from command line */
			(void)fprintf(el->el_outfile, "\n");

			/*
			 * If there are too many items, ask user for display
			 * confirmation.
			 */
			if (matches_num > query_items) {
				(void)fprintf(el->el_outfile,
				    "Display all %zu possibilities? (y or n) ",
				    matches_num);
				(void)fflush(el->el_outfile);
				if (getc(stdin) != 'y')
					match_display = 0;
				(void)fprintf(el->el_outfile, "\n");
			}

			if (match_display) {
				/*
				 * Interface of this function requires the
				 * strings be matches[1..num-1] for compat.
				 * We have matches_num strings not counting
				 * the prefix in matches[0], so we need to
				 * add 1 to matches_num for the call.
				 */
				fn_display_match_list(el, matches,
				    matches_num+1, maxlen);
			}
			retval = CC_REDISPLAY;
		} else if (matches[0][0]) {
			/*
			 * There was some common match, but the name was
			 * not complete enough. Next tab will print possible
			 * completions.
			 */
			el_beep(el);
		} else {
			/* lcd is not a valid object - further specification */
			/* is needed */
			el_beep(el);
			retval = CC_NORM;
		}

		/* free elements of array and the array itself */
		for (i = 0; matches[i]; i++)
			el_free(matches[i]);
		el_free(matches);
		matches = NULL;
	}
	el_free(temp);
	return retval;
}
예제 #11
0
/*
 * return first found file name starting by the ``text'' or NULL if no
 * such file can be found
 * value of ``state'' is ignored
 *
 * it's caller's responsibility to free returned string
 */
char *
fn_filename_completion_function(const char *text, int state)
{
	static DIR *dir = NULL;
	static char *filename = NULL, *dirname = NULL, *dirpath = NULL;
	static size_t filename_len = 0;
	struct dirent *entry;
	char *temp;
	size_t len;

	if (state == 0 || dir == NULL) {
		temp = strrchr(text, '/');
		if (temp) {
			char *nptr;
			temp++;
			nptr = el_realloc(filename, (strlen(temp) + 1) *
			    sizeof(*nptr));
			if (nptr == NULL) {
				el_free(filename);
				filename = NULL;
				return NULL;
			}
			filename = nptr;
			(void)strcpy(filename, temp);
			len = (size_t)(temp - text);	/* including last slash */

			nptr = el_realloc(dirname, (len + 1) *
			    sizeof(*nptr));
			if (nptr == NULL) {
				el_free(dirname);
				dirname = NULL;
				return NULL;
			}
			dirname = nptr;
			(void)strncpy(dirname, text, len);
			dirname[len] = '\0';
		} else {
			el_free(filename);
			if (*text == 0)
				filename = NULL;
			else {
				filename = strdup(text);
				if (filename == NULL)
					return NULL;
			}
			el_free(dirname);
			dirname = NULL;
		}

		if (dir != NULL) {
			(void)closedir(dir);
			dir = NULL;
		}

		/* support for ``~user'' syntax */

		el_free(dirpath);
		dirpath = NULL;
		if (dirname == NULL) {
			if ((dirname = strdup("")) == NULL)
				return NULL;
			dirpath = strdup("./");
		} else if (*dirname == '~')
			dirpath = fn_tilde_expand(dirname);
		else
			dirpath = strdup(dirname);

		if (dirpath == NULL)
			return NULL;

		dir = opendir(dirpath);
		if (!dir)
			return NULL;	/* cannot open the directory */

		/* will be used in cycle */
		filename_len = filename ? strlen(filename) : 0;
	}

	/* find the match */
	while ((entry = readdir(dir)) != NULL) {
		/* skip . and .. */
		if (entry->d_name[0] == '.' && (!entry->d_name[1]
		    || (entry->d_name[1] == '.' && !entry->d_name[2])))
			continue;
		if (filename_len == 0)
			break;
		/* otherwise, get first entry where first */
		/* filename_len characters are equal	  */
		if (entry->d_name[0] == filename[0]
          /* Some dirents have d_namlen, but it is not portable. */
		    && strlen(entry->d_name) >= filename_len
		    && strncmp(entry->d_name, filename,
			filename_len) == 0)
			break;
	}

	if (entry) {		/* match found */

       /* Some dirents have d_namlen, but it is not portable. */
		len = strlen(entry->d_name);

		len = strlen(dirname) + len + 1;
		temp = el_malloc(len * sizeof(*temp));
		if (temp == NULL)
			return NULL;
		(void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
	} else {
		(void)closedir(dir);
		dir = NULL;
		temp = NULL;
	}

	return temp;
}
예제 #12
0
/* ch_init():
 *	Initialize the character editor
 */
libedit_private int
ch_init(EditLine *el)
{
	c_macro_t *ma = &el->el_chared.c_macro;

	el->el_line.buffer		= el_malloc(EL_BUFSIZ *
	    sizeof(*el->el_line.buffer));
	if (el->el_line.buffer == NULL)
		return -1;

	(void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
	    sizeof(*el->el_line.buffer));
	el->el_line.cursor		= el->el_line.buffer;
	el->el_line.lastchar		= el->el_line.buffer;
	el->el_line.limit		= &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];

	el->el_chared.c_undo.buf	= el_malloc(EL_BUFSIZ *
	    sizeof(*el->el_chared.c_undo.buf));
	if (el->el_chared.c_undo.buf == NULL)
		return -1;
	(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
	    sizeof(*el->el_chared.c_undo.buf));
	el->el_chared.c_undo.len	= -1;
	el->el_chared.c_undo.cursor	= 0;
	el->el_chared.c_redo.buf	= el_malloc(EL_BUFSIZ *
	    sizeof(*el->el_chared.c_redo.buf));
	if (el->el_chared.c_redo.buf == NULL)
		return -1;
	el->el_chared.c_redo.pos	= el->el_chared.c_redo.buf;
	el->el_chared.c_redo.lim	= el->el_chared.c_redo.buf + EL_BUFSIZ;
	el->el_chared.c_redo.cmd	= ED_UNASSIGNED;

	el->el_chared.c_vcmd.action	= NOP;
	el->el_chared.c_vcmd.pos	= el->el_line.buffer;

	el->el_chared.c_kill.buf	= el_malloc(EL_BUFSIZ *
	    sizeof(*el->el_chared.c_kill.buf));
	if (el->el_chared.c_kill.buf == NULL)
		return -1;
	(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
	    sizeof(*el->el_chared.c_kill.buf));
	el->el_chared.c_kill.mark	= el->el_line.buffer;
	el->el_chared.c_kill.last	= el->el_chared.c_kill.buf;
	el->el_chared.c_resizefun	= NULL;
	el->el_chared.c_resizearg	= NULL;
	el->el_chared.c_aliasfun	= NULL;
	el->el_chared.c_aliasarg	= NULL;

	el->el_map.current		= el->el_map.key;

	el->el_state.inputmode		= MODE_INSERT; /* XXX: save a default */
	el->el_state.doingarg		= 0;
	el->el_state.metanext		= 0;
	el->el_state.argument		= 1;
	el->el_state.lastcmd		= ED_UNASSIGNED;

	ma->level	= -1;
	ma->offset	= 0;
	ma->macro	= el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
	if (ma->macro == NULL)
		return -1;
	return 0;
}
예제 #13
0
파일: vi.c 프로젝트: DavidMulder/heimdal
/* vi_histedit():
 *	Vi edit history line with vi
 *	[v]
 */
libedit_private el_action_t
/*ARGSUSED*/
vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
{
	int fd;
	pid_t pid;
	ssize_t st;
	int status;
	char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
	char *cp = NULL;
	size_t len;
	wchar_t *line = NULL;

	if (el->el_state.doingarg) {
		if (vi_to_history_line(el, 0) == CC_ERROR)
			return CC_ERROR;
	}

	fd = mkstemp(tempfile);
	if (fd < 0)
		return CC_ERROR;
	len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
	cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
	if (cp == NULL)
		goto error;
	line = el_malloc(len * sizeof(*line) + 1);
	if (line == NULL)
		goto error;
	wcsncpy(line, el->el_line.buffer, len);
	line[len] = '\0';
	wcstombs(cp, line, TMP_BUFSIZ - 1);
	cp[TMP_BUFSIZ - 1] = '\0';
	len = strlen(cp);
	write(fd, cp, len);
	write(fd, "\n", (size_t)1);
	pid = fork();
	switch (pid) {
	case -1:
		goto error;
	case 0:
		close(fd);
		execlp("vi", "vi", tempfile, (char *)NULL);
		exit(0);
		/*NOTREACHED*/
	default:
		while (waitpid(pid, &status, 0) != pid)
			continue;
		lseek(fd, (off_t)0, SEEK_SET);
		st = read(fd, cp, TMP_BUFSIZ - 1);
		if (st > 0) {
			cp[st] = '\0';
			len = (size_t)(el->el_line.limit - el->el_line.buffer);
			len = mbstowcs(el->el_line.buffer, cp, len);
			if (len > 0 && el->el_line.buffer[len - 1] == '\n')
				--len;
		}
		else
			len = 0;
                el->el_line.cursor = el->el_line.buffer;
                el->el_line.lastchar = el->el_line.buffer + len;
		el_free(cp);
                el_free(line);
		break;
	}

	close(fd);
	unlink(tempfile);
	/* return CC_REFRESH; */
	return ed_newline(el, 0);
error:
	el_free(line);
	el_free(cp);
	close(fd);
	unlink(tempfile);
	return CC_ERROR;
}
예제 #14
0
static char *
escape_filename(EditLine * el, const char *filename)
{
	size_t original_len = 0;
	size_t escaped_character_count = 0;
	size_t offset = 0;
	size_t newlen;
	const char *s;
	char c;
	size_t s_quoted = 0;	/* does the input contain a single quote */
	size_t d_quoted = 0;	/* does the input contain a double quote */
	char *escaped_str;
	wchar_t *temp = el->el_line.buffer;

	while (temp != el->el_line.cursor) {
		/*
		 * If we see a single quote but have not seen a double quote so far
		 * set/unset s_quote
		 */
		if (temp[0] == '\'' && !d_quoted)
			s_quoted = !s_quoted;
		/*
		 * vice versa to the above condition
		 */
		else if (temp[0] == '"' && !s_quoted)
			d_quoted = !d_quoted;
		temp++;
	}

	/* Count number of special characters so that we can calculate
	 * number of extra bytes needed in the new string
	 */
	for (s = filename; *s; s++, original_len++) {
		c = *s;
		/* Inside a single quote only single quotes need escaping */
		if (s_quoted && c == '\'') {
			escaped_character_count += 3;
			continue;
		}
		/* Inside double quotes only ", \, ` and $ need escaping */
		if (d_quoted && (c == '"' || c == '\\' || c == '`' || c == '$')) {
			escaped_character_count++;
			continue;
		}
		if (!s_quoted && !d_quoted && needs_escaping(c))
			escaped_character_count++;
	}

	newlen = original_len + escaped_character_count + 1;
	if ((escaped_str = el_malloc(newlen)) == NULL)
		return NULL;

	for (s = filename; *s; s++) {
		c = *s;
		if (!needs_escaping(c)) {
			/* no escaping is required continue as usual */
			escaped_str[offset++] = c;
			continue;
		}

		/* single quotes inside single quotes require special handling */
		if (c == '\'' && s_quoted) {
			escaped_str[offset++] = '\'';
			escaped_str[offset++] = '\\';
			escaped_str[offset++] = '\'';
			escaped_str[offset++] = '\'';
			continue;
		}

		/* Otherwise no escaping needed inside single quotes */
		if (s_quoted) {
			escaped_str[offset++] = c;
			continue;
		}

		/* No escaping needed inside a double quoted string either
		 * unless we see a '$', '\', '`', or '"' (itself)
		 */
		if (d_quoted && c != '"' && c != '$' && c != '\\' && c != '`') {
			escaped_str[offset++] = c;
			continue;
		}

		/* If we reach here that means escaping is actually needed */
		escaped_str[offset++] = '\\';
		escaped_str[offset++] = c;
	}

	/* close the quotes */
	if (s_quoted)
		escaped_str[offset++] = '\'';
	else if (d_quoted)
		escaped_str[offset++] = '"';

	escaped_str[offset] = 0;
	return escaped_str;
}