diff options
author | obrien <obrien@FreeBSD.org> | 2007-12-05 15:48:03 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2007-12-05 15:48:03 +0000 |
commit | ea691ecd980d2860f0b39e9e504de4da404806fd (patch) | |
tree | fa83b3bb0660890a21b550fa1f334b151bf098f9 /contrib/amd/amd/mapc.c | |
parent | c06a2e613662fc6ce10145b41762be8f8ab22ba4 (diff) | |
download | FreeBSD-src-ea691ecd980d2860f0b39e9e504de4da404806fd.zip FreeBSD-src-ea691ecd980d2860f0b39e9e504de4da404806fd.tar.gz |
Virgin import of AMD (am-utils) v6.1.5
Sponsored by: Juniper Networks
Diffstat (limited to 'contrib/amd/amd/mapc.c')
-rw-r--r-- | contrib/amd/amd/mapc.c | 316 |
1 files changed, 115 insertions, 201 deletions
diff --git a/contrib/amd/amd/mapc.c b/contrib/amd/amd/mapc.c index 591c4f3..d7efdbc 100644 --- a/contrib/amd/amd/mapc.c +++ b/contrib/amd/amd/mapc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: mapc.c,v 1.7.2.7 2004/01/06 03:15:16 ezk Exp $ + * File: am-utils/amd/mapc.c * */ @@ -85,8 +84,6 @@ #define MREC_PART 1 #define MREC_NONE 0 -#define MAX_CHAIN 2048 - static struct opt_tab mapc_opt[] = { {"all", MAPC_ALL}, @@ -201,12 +198,17 @@ extern int ndbm_search(mnt_map *, char *, char *, char **, time_t *); extern int ndbm_mtime(mnt_map *, char *, time_t *); #endif /* HAVE_MAP_NDBM */ +/* EXECUTABLE MAPS */ +#ifdef HAVE_MAP_EXEC +extern int exec_init(mnt_map *, char *, time_t *); +extern int exec_search(mnt_map *, char *, char *, char **, time_t *); +#endif /* HAVE_MAP_EXEC */ + /* FILE MAPS */ #ifdef HAVE_MAP_FILE -extern int file_init(mnt_map *, char *, time_t *); +extern int file_init_or_mtime(mnt_map *, char *, time_t *); extern int file_reload(mnt_map *, char *, add_fn *); extern int file_search(mnt_map *, char *, char *, char **, time_t *); -extern int file_mtime(mnt_map *, char *, time_t *); #endif /* HAVE_MAP_FILE */ @@ -302,14 +304,25 @@ static map_type maptypes[] = #ifdef HAVE_MAP_FILE { "file", - file_init, + file_init_or_mtime, file_reload, NULL, /* isup function */ file_search, - file_mtime, + file_init_or_mtime, MAPC_ALL }, #endif /* HAVE_MAP_FILE */ +#ifdef HAVE_MAP_EXEC + { + "exec", + exec_init, + error_reload, + NULL, /* isup function */ + exec_search, + error_mtime, + MAPC_INC + }, +#endif /* HAVE_MAP_EXEC */ { "error", error_init, @@ -337,16 +350,27 @@ kvhash_of(char *key) void -mapc_showtypes(char *buf) +mapc_showtypes(char *buf, size_t l) { - map_type *mt; - char *sep = ""; + map_type *mt=NULL, *lastmt; + int linesize = 0, i; + i = sizeof(maptypes) / sizeof(maptypes[0]); + lastmt = maptypes + i; buf[0] = '\0'; - for (mt = maptypes; mt < maptypes + sizeof(maptypes) / sizeof(maptypes[0]); mt++) { - strcat(buf, sep); - strcat(buf, mt->name); - sep = ", "; + for (mt = maptypes; mt < lastmt; mt++) { + xstrlcat(buf, mt->name, l); + if (mt == (lastmt-1)) + break; /* if last one, don't do xstrlcat's that follows */ + linesize += strlen(mt->name); + if (--i > 0) { + xstrlcat(buf, ", ", l); + linesize += 2; + } + if (linesize > 54) { + linesize = 0; + xstrlcat(buf, "\n\t\t ", l); + } } } @@ -386,9 +410,7 @@ mapc_add_kv(mnt_map *m, char *key, char *val) regex_t re; #endif /* HAVE_REGEXEC */ -#ifdef DEBUG dlog("add_kv: %s -> %s", key, val); -#endif /* DEBUG */ #ifdef HAVE_REGEXEC if (MAPC_ISRE(m)) { @@ -398,7 +420,7 @@ mapc_add_kv(mnt_map *m, char *key, char *val) /* * Make sure the string is bound to the start and end */ - sprintf(pattern, "^%s$", key); + xsnprintf(pattern, sizeof(pattern), "^%s$", key); retval = regcomp(&re, pattern, REG_ICASE); if (retval != 0) { char errstr[256]; @@ -492,11 +514,12 @@ mapc_find_wildcard(mnt_map *m) * Do a map reload. * Attempt to reload without losing current data by switching the hashes * round. + * If reloading was needed and succeeded, return 1; else return 0. */ -static void +static int mapc_reload_map(mnt_map *m) { - int error; + int error, ret = 0; kv *maphash[NKVHASH], *tmphash[NKVHASH]; time_t t; @@ -512,11 +535,9 @@ mapc_reload_map(mnt_map *m) if (m->reloads != 0 && do_mapc_reload != 0) { if (t <= m->modify) { plog(XLOG_INFO, "reload of map %s is not needed (in sync)", m->map_name); -#ifdef DEBUG dlog("map %s last load time is %d, last modify time is %d", m->map_name, (int) m->modify, (int) t); -#endif /* DEBUG */ - return; + return ret; } } @@ -524,9 +545,7 @@ mapc_reload_map(mnt_map *m) memcpy((voidp) maphash, (voidp) m->kvhash, sizeof(m->kvhash)); memset((voidp) m->kvhash, 0, sizeof(m->kvhash)); -#ifdef DEBUG dlog("calling map reload on %s", m->map_name); -#endif /* DEBUG */ error = (*m->reload) (m, m->map_name, mapc_add_kv); if (error) { if (m->reloads == 0) @@ -547,15 +566,15 @@ mapc_reload_map(mnt_map *m) mapc_clear(m); memcpy((voidp) m->kvhash, (voidp) tmphash, sizeof(m->kvhash)); m->modify = t; + ret = 1; } m->wildcard = 0; -#ifdef DEBUG dlog("calling mapc_search for wildcard"); -#endif /* DEBUG */ error = mapc_search(m, wildcard, &m->wildcard); if (error) m->wildcard = 0; + return ret; } @@ -567,7 +586,7 @@ mapc_create(char *map, char *opt, const char *type) { mnt_map *m = ALLOC(struct mnt_map); map_type *mt; - time_t modify; + time_t modify = 0; int alloc = 0; cmdoption(opt, mapc_opt, &alloc); @@ -603,9 +622,7 @@ mapc_create(char *map, char *opt, const char *type) for (mt = maptypes; mt < maptypes + sizeof(maptypes) / sizeof(maptypes[0]); mt++) { -#ifdef DEBUG dlog("trying to initialize map %s of type %s ...", map, mt->name); -#endif /* DEBUG */ if ((*mt->init) (m, map, &modify) == 0) { break; } @@ -652,9 +669,7 @@ mapc_create(char *map, char *opt, const char *type) #endif /* HAVE_REGEXEC */ } -#ifdef DEBUG dlog("Map for %s coming from maptype %s", map, mt->name); -#endif /* DEBUG */ m->alloc = alloc; m->reload = mt->reload; @@ -667,6 +682,8 @@ mapc_create(char *map, char *opt, const char *type) m->refc = 1; m->wildcard = 0; m->reloads = 0; + /* Unfortunately with current code structure, this cannot be initialized here */ + m->cfm = NULL; /* * synchronize cache with reality @@ -732,7 +749,7 @@ mapc_find(char *map, char *opt, const char *maptype) * add it to the list of maps */ ITER(m, mnt_map, &map_list_head) - if (STREQ(m->map_name, map)) + if (STREQ(m->map_name, map)) return mapc_dup(m); m = mapc_create(map, opt, maptype); ins_que(&m->hdr, &map_list_head); @@ -745,9 +762,9 @@ mapc_find(char *map, char *opt, const char *maptype) * Free a map. */ void -mapc_free(voidp v) +mapc_free(opaque_t arg) { - mnt_map *m = v; + mnt_map *m = (mnt_map *) arg; /* * Decrement the reference count. @@ -883,12 +900,15 @@ mapc_meta_search(mnt_map *m, char *key, char **pval, int recurse) * For example: * "src/gnu/gcc" -> "src / gnu / *" -> "src / *" */ - strcpy(wildname, key); + xstrlcpy(wildname, key, sizeof(wildname)); while (error && (subp = strrchr(wildname, '/'))) { - strcpy(subp, "/*"); -#ifdef DEBUG + /* + * sizeof space left in subp is sizeof wildname minus what's left + * after the strchr above returned a pointer inside wildname into + * subp. + */ + xstrlcpy(subp, "/*", sizeof(wildname) - (subp - wildname)); dlog("mapc recurses on %s", wildname); -#endif /* DEBUG */ error = mapc_meta_search(m, wildname, pval, MREC_PART); if (error) *subp = 0; @@ -917,25 +937,42 @@ mapc_search(mnt_map *m, char *key, char **pval) static void mapc_sync(mnt_map *m) { - if (m->alloc != MAPC_ROOT) { + int need_mtime_update = 0; - /* do not clear map if map service is down */ - if (m->isup) { - if (!((*m->isup)(m, m->map_name))) { - plog(XLOG_ERROR, "mapc_sync: map %s is down: not clearing map", m->map_name); - return; - } + if (m->alloc == MAPC_ROOT) + return; /* nothing to do */ + + /* do not clear map if map service is down */ + if (m->isup) { + if (!((*m->isup)(m, m->map_name))) { + plog(XLOG_ERROR, "mapc_sync: map %s is down: not clearing map", m->map_name); + return; } + } + + if (m->alloc >= MAPC_ALL) { + /* mapc_reload_map() always works */ + need_mtime_update = mapc_reload_map(m); + } else { + mapc_clear(m); + /* + * Attempt to find the wildcard entry + */ + mapc_find_wildcard(m); + need_mtime_update = 1; /* because mapc_clear always works */ + } - if (m->alloc >= MAPC_ALL) { - /* mapc_reload_map() always works */ - mapc_reload_map(m); + /* + * To be safe, update the mtime of the mnt_map's own node, so that the + * kernel will flush all of its cached entries. + */ + if (need_mtime_update && m->cfm) { + am_node *mp = find_ap(m->cfm->cfm_dir); + if (mp) { + clocktime(&mp->am_fattr.na_mtime); } else { - mapc_clear(m); - /* - * Attempt to find the wildcard entry - */ - mapc_find_wildcard(m); + plog(XLOG_ERROR, "cannot find map %s to update its mtime", + m->cfm->cfm_dir); } } } @@ -972,7 +1009,7 @@ mapc_reload(void) static int root_init(mnt_map *m, char *map, time_t *tp) { - *tp = clocktime(); + *tp = clocktime(NULL); return STREQ(map, ROOT_MAP) ? 0 : ENOENT; } @@ -1007,36 +1044,39 @@ root_newmap(const char *dir, const char *opts, const char *map, const cf_map_t * if (cfm) { if (map) { - sprintf(str, "cache:=mapdefault;type:=toplvl;fs:=\"%s\"", - get_full_path(map, cfm->cfm_search_path, cfm->cfm_type)); + xsnprintf(str, sizeof(str), + "cache:=mapdefault;type:=toplvl;mount_type:=%s;fs:=\"%s\"", + cfm->cfm_flags & CFM_MOUNT_TYPE_AUTOFS ? "autofs" : "nfs", + get_full_path(map, cfm->cfm_search_path, cfm->cfm_type)); if (opts && opts[0] != '\0') { - strcat(str, ";"); - strcat(str, opts); + xstrlcat(str, ";", sizeof(str)); + xstrlcat(str, opts, sizeof(str)); } if (cfm->cfm_flags & CFM_BROWSABLE_DIRS_FULL) - strcat(str, ";opts:=rw,fullybrowsable"); + xstrlcat(str, ";opts:=rw,fullybrowsable", sizeof(str)); if (cfm->cfm_flags & CFM_BROWSABLE_DIRS) - strcat(str, ";opts:=rw,browsable"); + xstrlcat(str, ";opts:=rw,browsable", sizeof(str)); if (cfm->cfm_type) { - strcat(str, ";maptype:="); - strcat(str, cfm->cfm_type); + xstrlcat(str, ";maptype:=", sizeof(str)); + xstrlcat(str, cfm->cfm_type, sizeof(str)); } } else { - strcpy(str, opts); + xstrlcpy(str, opts, sizeof(str)); } } else { if (map) - sprintf(str, "cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s", - map, opts ? opts : ""); + xsnprintf(str, sizeof(str), + "cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s", + map, opts ? opts : ""); else - strcpy(str, opts); + xstrlcpy(str, opts, sizeof(str)); } mapc_repl_kv(root_map, strdup((char *)dir), strdup(str)); } int -mapc_keyiter(mnt_map *m, void (*fn) (char *, voidp), voidp arg) +mapc_keyiter(mnt_map *m, key_fun *fn, opaque_t arg) { int i; int c = 0; @@ -1056,10 +1096,10 @@ mapc_keyiter(mnt_map *m, void (*fn) (char *, voidp), voidp arg) /* * Iterate on the root map and call (*fn)() on the key of all the nodes. - * Finally throw away the root map. + * Returns the number of entries in the root map. */ int -root_keyiter(void (*fn)(char *, voidp), voidp arg) +root_keyiter(key_fun *fn, opaque_t arg) { if (root_map) { int c = mapc_keyiter(root_map, fn, arg); @@ -1071,132 +1111,6 @@ root_keyiter(void (*fn)(char *, voidp), voidp arg) /* - * Was: NEW_TOPLVL_READDIR - * Search a chain for an entry with some name. - * -Erez Zadok <ezk@cs.columbia.edu> - */ -static int -key_already_in_chain(char *keyname, const nfsentry *chain) -{ - const nfsentry *tmpchain = chain; - - while (tmpchain) { - if (keyname && tmpchain->ne_name && STREQ(keyname, tmpchain->ne_name)) - return 1; - tmpchain = tmpchain->ne_nextentry; - } - - return 0; -} - - -/* - * Create a chain of entries which are not linked. - * -Erez Zadok <ezk@cs.columbia.edu> - */ -nfsentry * -make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable) -{ - static u_int last_cookie = (u_int) 2; /* monotonically increasing */ - static nfsentry chain[MAX_CHAIN]; - static int max_entries = MAX_CHAIN; - char *key; - int num_entries = 0, preflen = 0, i; - nfsentry *retval = (nfsentry *) NULL; - mntfs *mf; - mnt_map *mmp; - - if (!mp) { - plog(XLOG_DEBUG, "make_entry_chain: mp is (NULL)"); - return retval; - } - mf = mp->am_mnt; - if (!mf) { - plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt is (NULL)"); - return retval; - } - mmp = (mnt_map *) mf->mf_private; - if (!mmp) { - plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt->mf_private is (NULL)"); - return retval; - } - - if (mp->am_pref) - preflen = strlen(mp->am_pref); - - /* iterate over keys */ - for (i = 0; i < NKVHASH; i++) { - kv *k; - for (k = mmp->kvhash[i]; k ; k = k->next) { - - /* - * Skip unwanted entries which are either not real entries or - * very difficult to interpret (wildcards...) This test needs - * lots of improvement. Any takers? - */ - key = k->key; - if (!key) - continue; - - /* Skip '*' */ - if (!fully_browsable && strchr(key, '*')) - continue; - - /* - * If the map has a prefix-string then check if the key starts with - * this string, and if it does, skip over this prefix. If it has a - * prefix and it doesn't match the start of the key, skip it. - */ - if (preflen && (preflen <= (strlen(key)))) { - if (!NSTREQ(key, mp->am_pref, preflen)) - continue; - key += preflen; - } else if (preflen) { - continue; - } - - /* no more '/' are allowed, unless browsable_dirs=full was used */ - if (!fully_browsable && strchr(key, '/')) - continue; - - /* no duplicates allowed */ - if (key_already_in_chain(key, current_chain)) - continue; - - /* fill in a cell and link the entry */ - if (num_entries >= max_entries) { - /* out of space */ - plog(XLOG_DEBUG, "make_entry_chain: no more space in chain"); - if (num_entries > 0) { - chain[num_entries - 1].ne_nextentry = 0; - retval = &chain[0]; - } - return retval; - } - - /* we have space. put entry in next cell */ - ++last_cookie; - chain[num_entries].ne_fileid = (u_int) last_cookie; - *(u_int *) chain[num_entries].ne_cookie = (u_int) last_cookie; - chain[num_entries].ne_name = key; - if (num_entries < max_entries - 1) { /* link to next one */ - chain[num_entries].ne_nextentry = &chain[num_entries + 1]; - } - ++num_entries; - } /* end of "while (k)" */ - } /* end of "for (i ... NKVHASH ..." */ - - /* terminate chain */ - if (num_entries > 0) { - chain[num_entries - 1].ne_nextentry = 0; - retval = &chain[0]; - } - - return retval; -} - - -/* * Error map */ static int @@ -1260,15 +1174,15 @@ get_full_path(const char *map, const char *path, const char *type) return map; /* now break path into components, and search in each */ - strcpy(component, path); + xstrlcpy(component, path, sizeof(component)); str = strtok(component, ":"); do { - strcpy(full_path, str); + xstrlcpy(full_path, str, sizeof(full_path)); len = strlen(full_path); if (full_path[len - 1] != '/') /* add trailing "/" if needed */ - strcat(full_path, "/"); - strcat(full_path, map); + xstrlcat(full_path, "/", sizeof(full_path)); + xstrlcat(full_path, map, sizeof(full_path)); if (access(full_path, R_OK) == 0) return full_path; str = strtok(NULL, ":"); |