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

📄 wordexp.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 4 页
字号:
/* vi: set sw=4 ts=4: *//* POSIX.2 wordexp implementation.   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.   This file is part of the GNU C Library.   Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.   The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Library General Public License as   published by the Free Software Foundation; either version 2 of the   License, or (at your option) any later version.   The GNU C Library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Library General Public License for more details.   You should have received a copy of the GNU Library General Public   License along with the GNU C Library; see the file COPYING.LIB.  If not,   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,   Boston, MA 02111-1307, USA.  */#define _GNU_SOURCE#include <sys/cdefs.h>#include <sys/types.h>#include <sys/wait.h>#include <fcntl.h>#include <paths.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <pwd.h>#include <errno.h>#include <assert.h>#include <fnmatch.h>#include <glob.h>#include <wordexp.h>#define __WORDEXP_FULL//#undef __WORDEXP_FULL/* * This is a recursive-descent-style word expansion routine. *//* These variables are defined and initialized in the startup code.  *///extern int __libc_argc;//extern char **__libc_argv;/* FIXME!!!! */int __libc_argc;char **__libc_argv;/* Some forward declarations */static int parse_dollars(char **word, size_t * word_length,						 size_t * max_length, const char *words,						 size_t * offset, int flags, wordexp_t * pwordexp,						 const char *ifs, const char *ifs_white,						 int quoted);static int parse_backtick(char **word, size_t * word_length,						  size_t * max_length, const char *words,						  size_t * offset, int flags, wordexp_t * pwordexp,						  const char *ifs, const char *ifs_white);static int parse_dquote(char **word, size_t * word_length,						size_t * max_length, const char *words,						size_t * offset, int flags, wordexp_t * pwordexp,						const char *ifs, const char *ifs_white);/* The w_*() functions manipulate word lists. */#define W_CHUNK	(100)/* Result of w_newword will be ignored if it's the last word. */static inline char *w_newword(size_t * actlen, size_t * maxlen){	*actlen = *maxlen = 0;	return NULL;}/* Add a character to the buffer, allocating room for it if needed.  */static inline char *w_addchar(char *buffer, size_t * actlen,							  size_t * maxlen, char ch)	 /* (lengths exclude trailing zero) */{	if (*actlen == *maxlen) {		char *old_buffer = buffer;		assert(buffer == NULL || *maxlen != 0);		*maxlen += W_CHUNK;		buffer = realloc(buffer, 1 + *maxlen);		if (buffer == NULL)			free(old_buffer);	}	if (buffer != NULL) {		buffer[*actlen] = ch;		buffer[++(*actlen)] = '\0';	}	return buffer;}#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )static char *w_addmem(char *buffer, size_t * actlen, size_t * maxlen,					  const char *str, size_t len){	/* Add a string to the buffer, allocating room for it if needed.	 */	if (*actlen + len > *maxlen) {		char *old_buffer = buffer;		assert(buffer == NULL || *maxlen != 0);		*maxlen += MAX(2 * len, W_CHUNK);		buffer = realloc(old_buffer, 1 + *maxlen);		if (buffer == NULL)			free(old_buffer);	}	if (buffer != NULL) {		*((char *) mempcpy(&buffer[*actlen], str, len)) = '\0';		*actlen += len;	}	return buffer;}/* Add a string to the buffer, allocating room for it if needed.  */static char *w_addstr(char *buffer, size_t * actlen, size_t * maxlen,					  const char *str)	 /* (lengths exclude trailing zero) */{	size_t len;	assert(str != NULL);		/* w_addstr only called from this file */	len = strlen(str);	return w_addmem(buffer, actlen, maxlen, str, len);}/* Add a word to the wordlist */static int w_addword(wordexp_t * pwordexp, char *word){	size_t num_p;	char **new_wordv;	/* Internally, NULL acts like "".  Convert NULLs to "" before	 * the caller sees them.	 */	if (word == NULL) {		word = strdup("");		if (word == NULL)			goto no_space;	}	num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;	new_wordv = realloc(pwordexp->we_wordv, sizeof(char *) * num_p);	if (new_wordv != NULL) {		pwordexp->we_wordv = new_wordv;		pwordexp->we_wordv[pwordexp->we_offs + pwordexp->we_wordc++] = word;		pwordexp->we_wordv[pwordexp->we_offs + pwordexp->we_wordc] = NULL;		return 0;	}  no_space:	return WRDE_NOSPACE;}/* The parse_*() functions should leave *offset being the offset in 'words' * to the last character processed. */static intparse_backslash(char **word, size_t * word_length, size_t * max_length,				const char *words, size_t * offset){	/* We are poised _at_ a backslash, not in quotes */	switch (words[1 + *offset]) {	case 0:		/* Backslash is last character of input words */		return WRDE_SYNTAX;	case '\n':		++(*offset);		break;	default:		*word = w_addchar(*word, word_length, max_length, words[1 + *offset]);		if (*word == NULL)			return WRDE_NOSPACE;		++(*offset);		break;	}	return 0;}static intparse_qtd_backslash(char **word, size_t * word_length, size_t * max_length,					const char *words, size_t * offset){	/* We are poised _at_ a backslash, inside quotes */	switch (words[1 + *offset]) {	case 0:		/* Backslash is last character of input words */		return WRDE_SYNTAX;	case '\n':		++(*offset);		break;	case '$':	case '`':	case '"':	case '\\':		*word =			w_addchar(*word, word_length, max_length, words[1 + *offset]);		if (*word == NULL)			return WRDE_NOSPACE;		++(*offset);		break;	default:		*word = w_addchar(*word, word_length, max_length, words[*offset]);		if (*word != NULL)			*word =				w_addchar(*word, word_length, max_length,						  words[1 + *offset]);		if (*word == NULL)			return WRDE_NOSPACE;		++(*offset);		break;	}	return 0;}static intparse_tilde(char **word, size_t * word_length, size_t * max_length,			const char *words, size_t * offset, size_t wordc){	/* We are poised _at_ a tilde */	size_t i;	if (*word_length != 0) {		if (!((*word)[*word_length - 1] == '=' && wordc == 0)) {			if (!((*word)[*word_length - 1] == ':'				  && strchr(*word, '=') && wordc == 0)) {				*word = w_addchar(*word, word_length, max_length, '~');				return *word ? 0 : WRDE_NOSPACE;			}		}	}	for (i = 1 + *offset; words[i]; i++) {		if (words[i] == ':' || words[i] == '/' || words[i] == ' ' ||			words[i] == '\t' || words[i] == 0)			break;		if (words[i] == '\\') {			*word = w_addchar(*word, word_length, max_length, '~');			return *word ? 0 : WRDE_NOSPACE;		}	}	if (i == 1 + *offset) {		/* Tilde appears on its own */		uid_t uid;		struct passwd pwd, *tpwd;		int buflen = 1000;		char *home;		char *buffer;		int result;		/* POSIX.2 says ~ expands to $HOME and if HOME is unset the		   results are unspecified.  We do a lookup on the uid if		   HOME is unset. */		home = getenv("HOME");		if (home != NULL) {			*word = w_addstr(*word, word_length, max_length, home);			if (*word == NULL)				return WRDE_NOSPACE;		} else {			uid = getuid();			buffer = alloca(buflen);			while ((result = getpwuid_r(uid, &pwd, buffer, buflen, &tpwd)) 					!= 0 && errno == ERANGE) 			{				buflen += 1000;				buffer = alloca(buflen);			}			if (result == 0 && tpwd != NULL && pwd.pw_dir != NULL) {				*word = w_addstr(*word, word_length, max_length, pwd.pw_dir);				if (*word == NULL)					return WRDE_NOSPACE;			} else {				*word = w_addchar(*word, word_length, max_length, '~');				if (*word == NULL)					return WRDE_NOSPACE;			}		}	} else {		/* Look up user name in database to get home directory */		char *user = strndup(&words[1 + *offset], i - (1 + *offset));		struct passwd pwd, *tpwd;		int buflen = 1000;		char *buffer = alloca(buflen);		int result;		while ((result = getpwnam_r(user, &pwd, buffer, buflen, &tpwd)) != 0			   && errno == ERANGE) {			buflen += 1000;			buffer = alloca(buflen);		}		if (result == 0 && tpwd != NULL && pwd.pw_dir)			*word = w_addstr(*word, word_length, max_length, pwd.pw_dir);		else {			/* (invalid login name) */			*word = w_addchar(*word, word_length, max_length, '~');			if (*word != NULL)				*word = w_addstr(*word, word_length, max_length, user);		}		*offset = i - 1;	}	return *word ? 0 : WRDE_NOSPACE;}static intdo_parse_glob(const char *glob_word, char **word, size_t * word_length,			  size_t * max_length, wordexp_t * pwordexp, const char *ifs,			  const char *ifs_white){	int error;	int match;	glob_t globbuf;	error = glob(glob_word, GLOB_NOCHECK, NULL, &globbuf);	if (error != 0) {		/* We can only run into memory problems.  */		assert(error == GLOB_NOSPACE);		return WRDE_NOSPACE;	}	if (ifs && !*ifs) {		/* No field splitting allowed. */		assert(globbuf.gl_pathv[0] != NULL);		*word = w_addstr(*word, word_length, max_length, globbuf.gl_pathv[0]);		for (match = 1; match < globbuf.gl_pathc && *word != NULL; ++match) {			*word = w_addchar(*word, word_length, max_length, ' ');			if (*word != NULL)				*word = w_addstr(*word, word_length, max_length,								 globbuf.gl_pathv[match]);		}		globfree(&globbuf);		return *word ? 0 : WRDE_NOSPACE;	}	assert(ifs == NULL || *ifs != '\0');	if (*word != NULL) {		free(*word);		*word = w_newword(word_length, max_length);	}	for (match = 0; match < globbuf.gl_pathc; ++match) {		char *matching_word = strdup(globbuf.gl_pathv[match]);		if (matching_word == NULL || w_addword(pwordexp, matching_word)) {			globfree(&globbuf);			return WRDE_NOSPACE;		}	}	globfree(&globbuf);	return 0;}static intparse_glob(char **word, size_t * word_length, size_t * max_length,		   const char *words, size_t * offset, int flags,		   wordexp_t * pwordexp, const char *ifs, const char *ifs_white){	/* We are poised just after a '*', a '[' or a '?'. */	int error = WRDE_NOSPACE;	int quoted = 0;				/* 1 if singly-quoted, 2 if doubly */	int i;	wordexp_t glob_list;		/* List of words to glob */	glob_list.we_wordc = 0;	glob_list.we_wordv = NULL;	glob_list.we_offs = 0;	for (; words[*offset] != '\0'; ++*offset) {		if ((ifs && strchr(ifs, words[*offset])) ||			(!ifs && strchr(" \t\n", words[*offset])))			/* Reached IFS */			break;		/* Sort out quoting */		if (words[*offset] == '\'') {			if (quoted == 0) {				quoted = 1;				continue;			} else if (quoted == 1) {				quoted = 0;				continue;			}		} else if (words[*offset] == '"') {			if (quoted == 0) {				quoted = 2;				continue;			} else if (quoted == 2) {				quoted = 0;				continue;			}		}		/* Sort out other special characters */		if (quoted != 1 && words[*offset] == '$') {			error = parse_dollars(word, word_length, max_length, words,								  offset, flags, &glob_list, ifs,								  ifs_white, quoted == 2);			if (error)				goto tidy_up;			continue;		} else if (words[*offset] == '\\') {			if (quoted)				error = parse_qtd_backslash(word, word_length, max_length,											words, offset);			else				error = parse_backslash(word, word_length, max_length,										words, offset);			if (error)				goto tidy_up;			continue;		}		*word = w_addchar(*word, word_length, max_length, words[*offset]);		if (*word == NULL)			goto tidy_up;	}	/* Don't forget to re-parse the character we stopped at. */	--*offset;	/* Glob the words */	error = w_addword(&glob_list, *word);	*word = w_newword(word_length, max_length);	for (i = 0; error == 0 && i < glob_list.we_wordc; i++)		error = do_parse_glob(glob_list.we_wordv[i], word, word_length,							  max_length, pwordexp, ifs, ifs_white);	/* Now tidy up */  tidy_up:	wordfree(&glob_list);	return error;}static intparse_squote(char **word, size_t * word_length, size_t * max_length,			 const char *words, size_t * offset){	/* We are poised just after a single quote */	for (; words[*offset]; ++(*offset)) {		if (words[*offset] != '\'') {			*word = w_addchar(*word, word_length, max_length, words[*offset]);			if (*word == NULL)				return WRDE_NOSPACE;		} else			return 0;	}	/* Unterminated string */	return WRDE_SYNTAX;}#ifdef __WORDEXP_FULLstatic int eval_expr(char *expr, long int *result);static char *_itoa(unsigned long long int value, char *buflim){	sprintf(buflim, "%llu", value);	return buflim;}/* Functions to evaluate an arithmetic expression */static int eval_expr_val(char **expr, long int *result){	int sgn = +1;	char *digit;	/* Skip white space */	for (digit = *expr; digit && *digit && isspace(*digit); ++digit);	switch (*digit) {	case '(':		/* Scan for closing paren */		for (++digit; **expr && **expr != ')'; ++(*expr));		/* Is there one? */		if (!**expr)			return WRDE_SYNTAX;		*(*expr)++ = 0;		if (eval_expr(digit, result))			return WRDE_SYNTAX;		return 0;	case '+':					/* Positive value */		++digit;		break;	case '-':					/* Negative value */		++digit;		sgn = -1;		break;	default:		if (!isdigit(*digit))			return WRDE_SYNTAX;	}	*result = 0;	for (; *digit && isdigit(*digit); ++digit)		*result = (*result * 10) + (*digit - '0');	*expr = digit;	*result *= sgn;	return 0;}static int eval_expr_multdiv(char **expr, long int *result){	long int arg;	/* Read a Value */	if (eval_expr_val(expr, result) != 0)		return WRDE_SYNTAX;	while (**expr) {		/* Skip white space */		for (; *expr && **expr && isspace(**expr); ++(*expr));		if (**expr == '*') {			++(*expr);			if (eval_expr_val(expr, &arg) != 0)				return WRDE_SYNTAX;

⌨️ 快捷键说明

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