⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmdedit.c

📁 shell-HHARM9200.rar 华恒 AT91rm9200 中Busybox shell的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}#ifdef CONFIG_FEATURE_COMMAND_TAB_COMPLETIONstatic int is_execute(const struct stat *st){	if ((!my_euid && (st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) ||		(my_uid == st->st_uid && (st->st_mode & S_IXUSR)) ||		(my_gid == st->st_gid && (st->st_mode & S_IXGRP)) ||		(st->st_mode & S_IXOTH)) return TRUE;	return FALSE;}#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETIONstatic char **username_tab_completion(char *ud, int *num_matches){	struct passwd *entry;	int userlen;	char *temp;	ud++;                           /* ~user/... to user/... */	userlen = strlen(ud);	if (num_matches == 0) {         /* "~/..." or "~user/..." */		char *sav_ud = ud - 1;		char *home = 0;		if (*ud == '/') {       /* "~/..."     */			home = home_pwd_buf;		} else {			/* "~user/..." */			temp = strchr(ud, '/');			*temp = 0;              /* ~user\0 */			entry = getpwnam(ud);			*temp = '/';            /* restore ~user/... */			ud = temp;			if (entry)				home = entry->pw_dir;		}		if (home) {			if ((userlen + strlen(home) + 1) < BUFSIZ) {				char temp2[BUFSIZ];     /* argument size */				/* /home/user/... */				sprintf(temp2, "%s%s", home, ud);				strcpy(sav_ud, temp2);			}		}		return 0;       /* void, result save to argument :-) */	} else {		/* "~[^/]*" */		char **matches = (char **) NULL;		int nm = 0;		setpwent();		while ((entry = getpwent()) != NULL) {			/* Null usernames should result in all users as possible completions. */			if ( /*!userlen || */ !strncmp(ud, entry->pw_name, userlen)) {			       bb_xasprintf(&temp, "~%s/", entry->pw_name);				matches = xrealloc(matches, (nm + 1) * sizeof(char *));				matches[nm++] = temp;			}		}		endpwent();		(*num_matches) = nm;		return (matches);	}}#endif  /* CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION */enum {	FIND_EXE_ONLY = 0,	FIND_DIR_ONLY = 1,	FIND_FILE_ONLY = 2,};#ifdef CONFIG_ASHconst char *cmdedit_path_lookup;#else#define cmdedit_path_lookup getenv("PATH")#endifstatic int path_parse(char ***p, int flags){	int npth;	const char *tmp;	const char *pth;	/* if not setenv PATH variable, to search cur dir "." */	if (flags != FIND_EXE_ONLY || (pth = cmdedit_path_lookup) == 0 ||		/* PATH=<empty> or PATH=:<empty> */		*pth == 0 || (*pth == ':' && *(pth + 1) == 0)) {		return 1;	}	tmp = pth;	npth = 0;	for (;;) {		npth++;                 /* count words is + 1 count ':' */		tmp = strchr(tmp, ':');		if (tmp) {			if (*++tmp == 0)				break;  /* :<empty> */		} else			break;	}	*p = xmalloc(npth * sizeof(char *));	tmp = pth;	(*p)[0] = bb_xstrdup(tmp);	npth = 1;                       /* count words is + 1 count ':' */	for (;;) {		tmp = strchr(tmp, ':');		if (tmp) {			(*p)[0][(tmp - pth)] = 0;       /* ':' -> '\0' */			if (*++tmp == 0)				break;                  /* :<empty> */		} else			break;		(*p)[npth++] = &(*p)[0][(tmp - pth)];   /* p[next]=p[0][&'\0'+1] */	}	return npth;}static char *add_quote_for_spec_chars(char *found){	int l = 0;	char *s = xmalloc((strlen(found) + 1) * 2);	while (*found) {		if (strchr(" `\"#$%^&*()=+{}[]:;\'|\\<>", *found))			s[l++] = '\\';		s[l++] = *found++;	}	s[l] = 0;	return s;}static char **exe_n_cwd_tab_completion(char *command, int *num_matches,					int type){	char **matches = 0;	DIR *dir;	struct dirent *next;	char dirbuf[BUFSIZ];	int nm = *num_matches;	struct stat st;	char *path1[1];	char **paths = path1;	int npaths;	int i;	char *found;	char *pfind = strrchr(command, '/');	path1[0] = ".";	if (pfind == NULL) {		/* no dir, if flags==EXE_ONLY - get paths, else "." */		npaths = path_parse(&paths, type);		pfind = command;	} else {		/* with dir */		/* save for change */		strcpy(dirbuf, command);		/* set dir only */		dirbuf[(pfind - command) + 1] = 0;#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION		if (dirbuf[0] == '~')   /* ~/... or ~user/... */			username_tab_completion(dirbuf, 0);#endif		/* "strip" dirname in command */		pfind++;		paths[0] = dirbuf;		npaths = 1;                             /* only 1 dir */	}	for (i = 0; i < npaths; i++) {		dir = opendir(paths[i]);		if (!dir)                       /* Don't print an error */			continue;		while ((next = readdir(dir)) != NULL) {			char *str_found = next->d_name;			/* matched ? */			if (strncmp(str_found, pfind, strlen(pfind)))				continue;			/* not see .name without .match */			if (*str_found == '.' && *pfind == 0) {				if (*paths[i] == '/' && paths[i][1] == 0					&& str_found[1] == 0) str_found = "";   /* only "/" */				else					continue;			}			found = concat_path_file(paths[i], str_found);			/* hmm, remover in progress? */			if (stat(found, &st) < 0)				goto cont;			/* find with dirs ? */			if (paths[i] != dirbuf)				strcpy(found, next->d_name);    /* only name */			if (S_ISDIR(st.st_mode)) {				/* name is directory      */				str_found = found;				found = concat_path_file(found, "");				free(str_found);				str_found = add_quote_for_spec_chars(found);			} else {				/* not put found file if search only dirs for cd */				if (type == FIND_DIR_ONLY)					goto cont;				str_found = add_quote_for_spec_chars(found);				if (type == FIND_FILE_ONLY ||					(type == FIND_EXE_ONLY && is_execute(&st)))					strcat(str_found, " ");			}			/* Add it to the list */			matches = xrealloc(matches, (nm + 1) * sizeof(char *));			matches[nm++] = str_found;cont:			free(found);		}		closedir(dir);	}	if (paths != path1) {		free(paths[0]);                 /* allocated memory only in first member */		free(paths);	}	*num_matches = nm;	return (matches);}static int match_compare(const void *a, const void *b){	return strcmp(*(char **) a, *(char **) b);}#define QUOT    (UCHAR_MAX+1)#define collapse_pos(is, in) { \	memcpy(int_buf+(is), int_buf+(in), (BUFSIZ+1-(is)-(in))*sizeof(int)); \	memcpy(pos_buf+(is), pos_buf+(in), (BUFSIZ+1-(is)-(in))*sizeof(int)); }static int find_match(char *matchBuf, int *len_with_quotes){	int i, j;	int command_mode;	int c, c2;	int int_buf[BUFSIZ + 1];	int pos_buf[BUFSIZ + 1];	/* set to integer dimension characters and own positions */	for (i = 0;; i++) {		int_buf[i] = (int) ((unsigned char) matchBuf[i]);		if (int_buf[i] == 0) {			pos_buf[i] = -1;        /* indicator end line */			break;		} else			pos_buf[i] = i;	}	/* mask \+symbol and convert '\t' to ' ' */	for (i = j = 0; matchBuf[i]; i++, j++)		if (matchBuf[i] == '\\') {			collapse_pos(j, j + 1);			int_buf[j] |= QUOT;			i++;#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT			if (matchBuf[i] == '\t')        /* algorithm equivalent */				int_buf[j] = ' ' | QUOT;#endif		}#ifdef CONFIG_FEATURE_NONPRINTABLE_INVERSE_PUT		else if (matchBuf[i] == '\t')			int_buf[j] = ' ';#endif	/* mask "symbols" or 'symbols' */	c2 = 0;	for (i = 0; int_buf[i]; i++) {		c = int_buf[i];		if (c == '\'' || c == '"') {			if (c2 == 0)				c2 = c;			else {				if (c == c2)					c2 = 0;				else					int_buf[i] |= QUOT;			}		} else if (c2 != 0 && c != '$')			int_buf[i] |= QUOT;	}	/* skip commands with arguments if line have commands delimiters */	/* ';' ';;' '&' '|' '&&' '||' but `>&' `<&' `>|' */	for (i = 0; int_buf[i]; i++) {		c = int_buf[i];		c2 = int_buf[i + 1];		j = i ? int_buf[i - 1] : -1;		command_mode = 0;		if (c == ';' || c == '&' || c == '|') {			command_mode = 1 + (c == c2);			if (c == '&') {				if (j == '>' || j == '<')					command_mode = 0;			} else if (c == '|' && j == '>')				command_mode = 0;		}		if (command_mode) {			collapse_pos(0, i + command_mode);			i = -1;                         /* hack incremet */		}	}	/* collapse `command...` */	for (i = 0; int_buf[i]; i++)		if (int_buf[i] == '`') {			for (j = i + 1; int_buf[j]; j++)				if (int_buf[j] == '`') {					collapse_pos(i, j + 1);					j = 0;					break;				}			if (j) {				/* not found close ` - command mode, collapse all previous */				collapse_pos(0, i + 1);				break;			} else				i--;                    /* hack incremet */		}	/* collapse (command...(command...)...) or {command...{command...}...} */	c = 0;                                          /* "recursive" level */	c2 = 0;	for (i = 0; int_buf[i]; i++)		if (int_buf[i] == '(' || int_buf[i] == '{') {			if (int_buf[i] == '(')				c++;			else				c2++;			collapse_pos(0, i + 1);			i = -1;                         /* hack incremet */		}	for (i = 0; pos_buf[i] >= 0 && (c > 0 || c2 > 0); i++)		if ((int_buf[i] == ')' && c > 0) || (int_buf[i] == '}' && c2 > 0)) {			if (int_buf[i] == ')')				c--;			else				c2--;			collapse_pos(0, i + 1);			i = -1;                         /* hack incremet */		}	/* skip first not quote space */	for (i = 0; int_buf[i]; i++)		if (int_buf[i] != ' ')			break;	if (i)		collapse_pos(0, i);	/* set find mode for completion */	command_mode = FIND_EXE_ONLY;	for (i = 0; int_buf[i]; i++)		if (int_buf[i] == ' ' || int_buf[i] == '<' || int_buf[i] == '>') {			if (int_buf[i] == ' ' && command_mode == FIND_EXE_ONLY				&& matchBuf[pos_buf[0]]=='c'				&& matchBuf[pos_buf[1]]=='d' )				command_mode = FIND_DIR_ONLY;			else {				command_mode = FIND_FILE_ONLY;				break;			}		}	/* "strlen" */	for (i = 0; int_buf[i]; i++);	/* find last word */	for (--i; i >= 0; i--) {		c = int_buf[i];		if (c == ' ' || c == '<' || c == '>' || c == '|' || c == '&') {			collapse_pos(0, i + 1);			break;		}	}	/* skip first not quoted '\'' or '"' */	for (i = 0; int_buf[i] == '\'' || int_buf[i] == '"'; i++);	/* collapse quote or unquote // or /~ */	while ((int_buf[i] & ~QUOT) == '/' &&			((int_buf[i + 1] & ~QUOT) == '/'			 || (int_buf[i + 1] & ~QUOT) == '~')) {		i++;	}	/* set only match and destroy quotes */	j = 0;	for (c = 0; pos_buf[i] >= 0; i++) {		matchBuf[c++] = matchBuf[pos_buf[i]];		j = pos_buf[i] + 1;	}	matchBuf[c] = 0;	/* old lenght matchBuf with quotes symbols */	*len_with_quotes = j ? j - pos_buf[0] : 0;	return command_mode;}/*   display by column original ideas from ls applet,   very optimize by my :)*/static void showfiles(char **matches, int nfiles){	int ncols, row;	int column_width = 0;	int nrows = nfiles;	/* find the longest file name-  use that as the column width */	for (row = 0; row < nrows; row++) {		int l = strlen(matches[row]);		if (column_width < l)			column_width = l;	}	column_width += 2;              /* min space for columns */	ncols = cmdedit_termw / column_width;	if (ncols > 1) {		nrows /= ncols;		if(nfiles % ncols)			nrows++;        /* round up fractionals */		column_width = -column_width;   /* for printf("%-Ns", ...); */	} else {		ncols = 1;	}	for (row = 0; row < nrows; row++) {		int n = row;		int nc;		for(nc = 1; nc < ncols && n+nrows < nfiles; n += nrows, nc++)			printf("%*s", column_width, matches[n]);		printf("%s\n", matches[n]);	}}static void input_tab(int *lastWasTab){	/* Do TAB completion */	static int num_matches;	static char **matches;	if (lastWasTab == 0) {          /* free all memory */		if (matches) {			while (num_matches > 0)				free(matches[--num_matches]);			free(matches);			matches = (char **) NULL;		}		return;	}	if (! *lastWasTab) {		char *tmp;		int len_found;		char matchBuf[BUFSIZ];		int find_type;		int recalc_pos;		*lastWasTab = TRUE;             /* flop trigger */		/* Make a local copy of the string -- up		 * to the position of the cursor */		tmp = strncpy(matchBuf, command_ps, cursor);		tmp[cursor] = 0;		find_type = find_match(matchBuf, &recalc_pos);		/* Free up any memory already allocated */		input_tab(0);#ifdef CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION		/* If the word starts with `~' and there is no slash in the word,		 * then try completing this word as a username. */		if (matchBuf[0] == '~' && strchr(matchBuf, '/') == 0)			matches = username_tab_completion(matchBuf, &num_matches);#endif		/* Try to match any executable in our path and everything		 * in the current working directory that matches.  */		if (!matches)			matches =				exe_n_cwd_tab_completion(matchBuf,					&num_matches, find_type);		/* Remove duplicate found */		if(matches) {			int i, j;			/* bubble */			for(i=0; i<(num_matches-1); i++)				for(j=i+1; j<num_matches; j++)					if(matches[i]!=0 && matches[j]!=0 &&						strcmp(matches[i], matches[j])==0) {							free(matches[j]);							matches[j]=0;					}			j=num_matches;			num_matches = 0;			for(i=0; i<j; i++)				if(matches[i]) {					if(!strcmp(matches[i], "./"))						matches[i][1]=0;					else if(!strcmp(matches[i], "../"))						matches[i][2]=0;					matches[num_matches++]=matches[i];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -