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

📄 opts.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			strncpy(ep, cp, len);			ep += len;		  } else {			plog(XLOG_ERROR, expand_error, *p->opt);			goto out;		  }		}		cp = dp + 1;		ch = *cp++;		if (ch == '$') {			if (BUFSPACE(ep, 1)) {				*ep++ = '$';			} else {				plog(XLOG_ERROR, expand_error, *p->opt);				goto out;			}		} else if (ch == '{') {			/* Expansion... */			enum { E_All, E_Dir, E_File, E_Domain, E_Host } todo;			/*			 * Find closing brace			 */			char *br_p = strchr(cp, '}');			int len;			/*			 * Check we found it			 */			if (!br_p) {				/*				 * Just give up				 */				plog(XLOG_USER, "No closing '}' in \"%s\"", *p->opt);				goto out;			}			len = br_p - cp;			/*			 * Figure out which part of the variable to grab.			 */			if (*cp == '/') {				/*				 * Just take the last component				 */				todo = E_File;				cp++;				--len;			} else if (br_p[-1] == '/') {				/*				 * Take all but the last component				 */				todo = E_Dir;				--len;			} else if (*cp == '.') {				/*				 * Take domain name				 */				todo = E_Domain;				cp++;				--len;			} else if (br_p[-1] == '.') {				/*				 * Take host name				 */				todo = E_Host;				--len;			} else {				/*				 * Take the whole lot				 */				todo = E_All;			}			/*			 * Truncate if too long.  Since it won't			 * match anyway it doesn't matter that			 * it has been cut short.			 */			if (len > NLEN)				len = NLEN;			/*			 * Put the string into another buffer so			 * we can do comparisons.			 */			strncpy(nbuf, cp, len);			nbuf[len] = '\0';			/*			 * Advance cp			 */			cp = br_p + 1;			/*			 * Search the option array			 */			for (op = opt_fields; op->name; op++) {				/*				 * Check for match				 */				if (len == op->nlen && STREQ(op->name, nbuf)) {					char xbuf[NLEN+3];					char *val;					/*					 * Found expansion.  Copy					 * the correct value field.					 */					if (!(!op->sel_p == !sel_p)) {						/*						 * Copy the string across unexpanded						 */						sprintf(xbuf, "${%s%s%s}",							todo == E_File ? "/" :								todo == E_Domain ? "." : "",							nbuf,							todo == E_Dir ? "/" :								todo == E_Host ? "." : "");						val = xbuf;						/*						 * Make sure expansion doesn't						 * munge the value!						 */						todo = E_All;					} else if (op->sel_p) {						val = *op->sel_p;					} else {						val = *op->optp;					}					if (val) {						/*						 * Do expansion:						 * ${/var} means take just the last part						 * ${var/} means take all but the last part						 * ${.var} means take all but first part						 * ${var.} means take just the first part						 * ${var} means take the whole lot						 */						int vlen = strlen(val);						char *vptr = val;						switch (todo) {						case E_Dir:							vptr = strrchr(val, '/');							if (vptr)								vlen = vptr - val;							vptr = val;							break;						case E_File:							vptr = strrchr(val, '/');							if (vptr) {								vptr++;								vlen = strlen(vptr);							} else								vptr = val;							break;						case E_Domain:							vptr = strchr(val, '.');							if (vptr) {								vptr++;								vlen = strlen(vptr);							} else {								vptr = "";								vlen = 0;							}							break;						case E_Host:							vptr = strchr(val, '.');							if (vptr)								vlen = vptr - val;							vptr = val;							break;						case E_All:							break;						}#ifdef DEBUG					/*dlog("Expanding \"%s\" to \"%s\"", nbuf, val);*/#endif /* DEBUG */						if (BUFSPACE(ep, vlen)) {							strcpy(ep, vptr);							ep += vlen;						} else {							plog(XLOG_ERROR, expand_error, *p->opt);							goto out;						}					}					/*					 * Done with this variable					 */					break;				}			}			/*			 * Check that the search was succesful			 */			if (!op->name) {				/*				 * If it wasn't then scan the				 * environment for that name				 * and use any value found				 */				char *env = getenv(nbuf);				if (env) {					int vlen = strlen(env);					if (BUFSPACE(ep, vlen)) {						strcpy(ep, env);						ep += vlen;					} else {						plog(XLOG_ERROR, expand_error, *p->opt);						goto out;					}#ifdef DEBUG					Debug(D_STR)					plog(XLOG_DEBUG, "Environment gave \"%s\" -> \"%s\"", nbuf, env);#endif /* DEBUG */				} else {					plog(XLOG_USER, "Unknown sequence \"${%s}\"", nbuf);				}			}		} else {			/*			 * Error, error			 */			plog(XLOG_USER, "Unknown $ sequence in \"%s\"", *p->opt);		}	}out:	/*	 * Handle common case - no expansion	 */	if (cp == *p->opt) {		*p->opt = strdup(cp);	} else {		/*		 * Finish off the expansion		 */		if (BUFSPACE(ep, strlen(cp))) {			strcpy(ep, cp);			/*ep += strlen(ep);*/		} else {			plog(XLOG_ERROR, expand_error, *p->opt);		}		/*		 * Save the exansion		 */		*p->opt = strdup(expbuf);	}	normalize_slash(*p->opt);#ifdef DEBUG	Debug(D_STR) {		plog(XLOG_DEBUG, "Expansion of \"%s\"...", cp_orig);		plog(XLOG_DEBUG, "... is \"%s\"", *p->opt);	}#endif /* DEBUG */}/* * Wrapper for expand_op */static void expand_opts P((opt_apply*, int));static void expand_opts(p, sel_p)opt_apply *p;int sel_p;{	if (*p->opt) {		expand_op(p, sel_p);	} else if (p->val) {		/*		 * Do double expansion, remembering		 * to free the string from the first		 * expansion...		 */		char *s = *p->opt = expand_key(p->val);		expand_op(p, sel_p);		free(s);	}}/* * Apply a function to a list of options */static void apply_opts(op, ppp, b)void (*op)();opt_apply ppp[];int b;{	opt_apply *pp;	for (pp = ppp; pp->opt; pp++)		(*op)(pp, b);}/* * Free the option table */void free_opts(fo)am_opts *fo;{	/*	 * Copy in the structure we are playing with	 */	fs_static = *fo;	/*	 * Free previously allocated memory	 */	apply_opts(free_op, to_free, FALSE);}/* * Expand lookup key */char *expand_key(key)char *key;{	opt_apply oa;	oa.opt = &key; oa.val = 0;	expand_opts(&oa, TRUE);	return key;}/* * Remove trailing /'s from a string * unless the string is a single / (Steven Glassman) */void deslashify P((char *s));void deslashify(s)char *s;{	if (s && *s) {		char *sl = s + strlen(s);		while (*--sl == '/' && sl > s)			*sl = '\0';	}}int eval_fs_opts(fo, opts, g_opts, path, key, map)am_opts *fo;char *opts, *g_opts, *path, *key, *map;{	int ok = TRUE;	free_opts(fo);	/*	 * Clear out the option table	 */	bzero((voidp) &fs_static, sizeof(fs_static));	bzero((voidp) vars, sizeof(vars));	bzero((voidp) fo, sizeof(*fo));	/*	 * Set key, map & path before expansion	 */	opt_key = key;	opt_map = map;	opt_path = path;	/*	 * Expand global options	 */	fs_static.fs_glob = expand_key(g_opts);	/*	 * Expand local options	 */	fs_static.fs_local = expand_key(opts);	/*	 * Expand default (global) options	 */	if (!eval_opts(fs_static.fs_glob, key))		ok = FALSE;	/*	 * Expand local options	 */	if (ok && !eval_opts(fs_static.fs_local, key))		ok = FALSE;	/*	 * Normalise remote host name.	 * 1.  Expand variables	 * 2.  Normalize relative to host tables	 * 3.  Strip local domains from the remote host	 *     name before using it in other expansions.	 *     This makes mount point names and other things	 *     much shorter, while allowing cross domain	 *     sharing of mount maps.	 */	apply_opts(expand_opts, rhost_expansion, FALSE);	if (ok && fs_static.opt_rhost && *fs_static.opt_rhost)		host_normalize(&fs_static.opt_rhost);	/*	 * Macro expand the options.	 * Do this regardless of whether we are accepting	 * this mount - otherwise nasty things happen	 * with memory allocation.	 */	apply_opts(expand_opts, expansions, FALSE);	/*	 * Strip trailing slashes from local pathname...	 */	deslashify(fs_static.opt_fs);	/*	 * ok... copy the data back out.	 */	*fo = fs_static;	/*	 * Clear defined options	 */	opt_key = opt_map = opt_path = nullstr;	return ok;}

⌨️ 快捷键说明

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