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

📄 mapc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (alloc == MAPC_DFLT)		alloc = mt->def_alloc;	switch (alloc) {	default:		plog(XLOG_USER, "Ambiguous map cache type \"%s\"; using \"inc\"", opt);		alloc = MAPC_INC;		/* fallthrough... */	case MAPC_NONE:	case MAPC_INC:	case MAPC_ROOT:		break;	case MAPC_ALL:		/*		 * If there is no support for reload and it was requested		 * then back off to incremental instead.		 */		if (mt->reload == error_reload) {			plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"all\"; using \"inc\"", mt->name);			alloc = MAPC_INC;		}		break;#ifdef HAS_REGEXP	case MAPC_RE:		if (mt->reload == error_reload) {			plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"re\"", mt->name);			mt = &maptypes[sizeof(maptypes)/sizeof(maptypes[0]) - 1];			/* assert: mt->name == "error" */		}		break;#endif	}#ifdef DEBUG	dlog("Map for %s coming from maptype %s", map, mt->name);#endif	m->alloc = alloc;	m->reload = mt->reload;	m->modify = modify;	m->search = alloc >= MAPC_ALL ? error_search : mt->search;	m->mtime = mt->mtime;	bzero((voidp) m->kvhash, sizeof(m->kvhash));	m->map_name = strdup(map);	m->refc = 1;	m->wildcard = 0;	/*	 * synchronize cache with reality	 */	mapc_sync(m);	return m;}/* * Free the cached data in a map */static void mapc_clear P((mnt_map *m));static void mapc_clear(m)mnt_map *m;{	int i;	/*	 * For each of the hash slots, chain	 * along free'ing the data.	 */	for (i = 0; i < NKVHASH; i++) {		kv *k = m->kvhash[i];		while (k) {			kv *n = k->next;			free((voidp) k->key);			if (k->val)				free((voidp) k->val);			free((voidp) k);			k = n;		}	}	/*	 * Zero the hash slots	 */	bzero((voidp) m->kvhash, sizeof(m->kvhash));	/*	 * Free the wildcard if it exists	 */	if (m->wildcard) {		free(m->wildcard);		m->wildcard = 0;	}}/* * Find a map, or create one if it does not exist */mnt_map *mapc_find P((char *map, char *opt));mnt_map *mapc_find(map, opt)char *map;char *opt;{	mnt_map *m;	/*	 * Search the list of known maps to see if	 * it has already been loaded.  If it is found	 * then return a duplicate reference to it.	 * Otherwise make a new map as required and	 * add it to the list of maps	 */	ITER(m, mnt_map, &map_list_head)		if (STREQ(m->map_name, map))			return mapc_dup(m);	m = mapc_create(map, opt);	ins_que(&m->hdr, &map_list_head);	return m;}/* * Free a map. */void mapc_free P((mnt_map *m));void mapc_free(m)mnt_map *m;{	/*	 * Decrement the reference count.	 * If the reference count hits zero	 * then throw the map away.	 */	if (m && --m->refc == 0) {		mapc_clear(m);		free((voidp) m->map_name);		rem_que(&m->hdr);		free((voidp) m);	}}/* * Search the map for the key. * Put a safe copy in *pval or return * an error code */int mapc_meta_search P((mnt_map *m, char *key, char **pval, int recurse));int mapc_meta_search(m, key, pval, recurse)mnt_map *m;char *key;char **pval;int recurse;{	int error = 0;	kv *k = 0;	/*	 * Firewall	 */	if (!m) {		plog(XLOG_ERROR, "Null map request for %s", key);		return ENOENT;	}	if (m->flags & MAPC_SYNC) {		/*		 * Get modify time...		 */		time_t t;		error = (*m->mtime)(m->map_name, &t);		if (error || t > m->modify) {			m->modify = t;			plog(XLOG_INFO, "Map %s is out of date", m->map_name);			mapc_sync(m);		}	}	if (!MAPC_ISRE(m)) {		/*		 * Compute the hash table offset		 */		k = m->kvhash[kvhash_of(key)];		/*		 * Scan the linked list for the key		 */		while (k && !FSTREQ(k->key, key)) k = k->next;	}#ifdef HAS_REGEXP	else if (recurse == MREC_FULL) {		/*		 * Try for an RE match against the entire map.		 * Note that this will be done in a "random"		 * order.		 */		int i;		for (i = 0; i < NKVHASH; i++) {			k = m->kvhash[i];			while (k) {				if (regexec((regexp *) k->key, key))					break;				k = k->next;			}			if (k)				break;		}	}#endif	/*	 * If found then take a copy	 */	if (k) {		if (k->val)			*pval = strdup(k->val);		else			error = ENOENT;	} else if (m->alloc >= MAPC_ALL) {		/*		 * If the entire map is cached then this		 * key does not exist.		 */		error = ENOENT;	} else {		/*		 * Otherwise search the map.  If we are		 * in incremental mode then add the key		 * to the cache.		 */		error = search_map(m, key, pval);		if (!error && m->alloc == MAPC_INC)			mapc_add_kv(m, strdup(key), strdup(*pval));	}	/*	 * If an error, and a wildcard exists,	 * and the key is not internal then	 * return a copy of the wildcard.	 */	if (error > 0) {		if (recurse == MREC_FULL && !MAPC_ISRE(m)) {			char wildname[MAXPATHLEN];			char *subp;			if (*key == '/')				return error;			/*			 * Keep chopping sub-directories from the RHS			 * and replacing with "/ *" and repeat the lookup.			 * For example:			 * "src/gnu/gcc" -> "src / gnu / *" -> "src / *"			 */			strcpy(wildname, key);			while (error && (subp = strrchr(wildname, '/'))) {				strcpy(subp, "/*");#ifdef DEBUG				dlog("mapc recurses on %s", wildname);#endif				error = mapc_meta_search(m, wildname, pval, MREC_PART);				if (error)					*subp = 0;			}			if (error > 0 && m->wildcard) {				*pval = strdup(m->wildcard);				error = 0;			}		}	}	return error;}int mapc_search P((mnt_map *m, char *key, char **pval));int mapc_search(m, key, pval)mnt_map *m;char *key;char **pval;{	return mapc_meta_search(m, key, pval, MREC_FULL);}/* * Get map cache in sync with physical representation */static void mapc_sync P((mnt_map *m));static void mapc_sync(m)mnt_map *m;{	if (m->alloc != MAPC_ROOT) {		mapc_clear(m);		if (m->alloc >= MAPC_ALL)			if (mapc_reload_map(m))				m->alloc = MAPC_INC;		/*		 * Attempt to find the wildcard entry		 */		if (m->alloc < MAPC_ALL)			mapc_find_wildcard(m);	}}/* * Reload all the maps * Called when Amd gets hit by a SIGHUP. */void mapc_reload(P_void);void mapc_reload(){	mnt_map *m;	/*	 * For all the maps,	 * Throw away the existing information.	 * Do a reload	 * Find the wildcard	 */	ITER(m, mnt_map, &map_list_head)		mapc_sync(m);}/* * Root map. * The root map is used to bootstrap amd. * All the require top-level mounts are added * into the root map and then the map is iterated * and a lookup is done on all the mount points. * This causes the top level mounts to be automounted. */static int root_init P((char *map, time_t *tp));static int root_init(map, tp)char *map;time_t *tp;{	*tp = clocktime();	return strcmp(map, ROOT_MAP) == 0 ? 0 : ENOENT;}/* * Add a new entry to the root map * * dir - directory (key) * opts - mount options * map - map name */void root_newmap P((char *dir, char *opts, char *map));void root_newmap(dir, opts, map)char *dir;char *opts;char *map;{	char str[MAXPATHLEN];	/*	 * First make sure we have a root map to talk about...	 */	if (!root_map)		root_map = mapc_find(ROOT_MAP, "mapdefault");	/*	 * Then add the entry...	 */	dir = strdup(dir);	if (map)		sprintf(str, "cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s",			map, opts ? opts : "");	else		strcpy(str, opts);	mapc_repl_kv(root_map, dir, strdup(str));}int mapc_keyiter P((mnt_map *m, void (*fn)(char*,voidp), voidp arg));int mapc_keyiter(m, fn, arg)mnt_map *m;void (*fn)P((char*, voidp));voidp arg;{	int i;	int c = 0;	for (i = 0; i < NKVHASH; i++) {		kv *k = m->kvhash[i];		while (k) {			(*fn)(k->key, arg);			k = k->next;			c++;		}	}	return c;}/* * Iterate of the the root map * and call (*fn)() on the key * of all the nodes. * Finally throw away the root map. */int root_keyiter P((void (*fn)(char*,voidp), voidp arg));int root_keyiter(fn, arg)void (*fn)P((char*,voidp));voidp arg;{	if (root_map) {		int c = mapc_keyiter(root_map, fn, arg);#ifdef notdef		mapc_free(root_map);		root_map = 0;#endif		return c;	}	return 0;}/* * Error map */static int error_init P((char *map, time_t *tp));static int error_init(map, tp)char *map;time_t *tp;{	plog(XLOG_USER, "No source data for map %s", map);	*tp = 0;	return 0;}/*ARGSUSED*/static int error_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp));static int error_search(m, map, key, pval, tp)mnt_map *m;char *map;char *key;char **pval;time_t *tp;{	return ENOENT;}/*ARGSUSED*/static int error_reload P((mnt_map *m, char *map, add_fn *fn));static int error_reload(m, map, fn)mnt_map *m;char *map;add_fn *fn;{	return ENOENT;}static int error_mtime P((char *map, time_t *tp));static int error_mtime(map, tp)char *map;time_t *tp;{	*tp = 0;	return 0;}

⌨️ 快捷键说明

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