/* * Crack a SunOS4-style host:fs:sub-link line * Construct an amd-style line and call the * normal amd matcher. */ am_ops * sunos4_match(am_opts *fo, char *key, char *g_key, char *path, char *keym, char *map) { char *host = key; char *fs = strchr(host, ':'); char *sublink = fs ? strchr(fs+1, ':') : 0; char keybuf[MAXPATHLEN]; snprintf(keybuf, sizeof(keybuf), "type:=nfs;rhost:=%s;rfs:=%s;sublink:=%s;opts:=%s", host, fs ? fs+1 : "", sublink ? sublink+1 : "", g_key); return ops_match(fo, keybuf, "", path, keym, map); }
static char * amfs_parse_defaults(am_node *mp, mntfs *mf, char *def_opts) { char *dflts; char *dfl; char **rvec = NULL; struct mnt_map *mm = (mnt_map *) mf->mf_private; dlog("determining /defaults entry value"); /* * Find out if amd.conf overrode any map-specific /defaults. */ if (mm->cfm && mm->cfm->cfm_defaults) { dlog("map %s map_defaults override: %s", mf->mf_mount, mm->cfm->cfm_defaults); dflts = xstrdup(mm->cfm->cfm_defaults); } else if (mapc_search(mm, "/defaults", &dflts) == 0) { dlog("/defaults gave %s", dflts); } else { return def_opts; /* if nothing found */ } /* trim leading '-' in case thee's one */ if (*dflts == '-') dfl = dflts + 1; else dfl = dflts; /* * Chop the defaults up */ rvec = strsplit(dfl, ' ', '\"'); if (gopt.flags & CFM_SELECTORS_IN_DEFAULTS) { /* * Pick whichever first entry matched the list of selectors. * Strip the selectors from the string, and assign to dfl the * rest of the string. */ if (rvec) { am_opts ap; am_ops *pt; char **sp = rvec; while (*sp) { /* loop until you find something, if any */ memset((char *) &ap, 0, sizeof(am_opts)); /* * This next routine cause many spurious "expansion of ... is" * messages, which are ignored, b/c all we need out of this * routine is to match selectors. These spurious messages may * be wrong, esp. if they try to expand ${key} b/c it will * get expanded to "/defaults" */ pt = ops_match(&ap, *sp, "", mp->am_path, "/defaults", mp->am_parent->am_al->al_mnt->mf_info); free_opts(&ap); /* don't leak */ if (pt == &amfs_error_ops) { plog(XLOG_MAP, "did not match defaults for \"%s\"", *sp); } else { dfl = strip_selectors(*sp, "/defaults"); plog(XLOG_MAP, "matched default selectors \"%s\"", dfl); break; } ++sp; } } } else { /* not selectors_in_defaults */ /* * Extract first value */ dfl = rvec[0]; } /* * If there were any values at all... */ if (dfl) { /* * Log error if there were other values */ if (!(gopt.flags & CFM_SELECTORS_IN_DEFAULTS) && rvec[1]) { dlog("/defaults chopped into %s", dfl); plog(XLOG_USER, "More than a single value for /defaults in %s", mf->mf_info); } /* * Prepend to existing defaults if they exist, * otherwise just use these defaults. */ if (*def_opts && *dfl) { size_t l = strlen(def_opts) + strlen(dfl) + 2; char *nopts = (char *) xmalloc(l); xsnprintf(nopts, l, "%s;%s", dfl, def_opts); XFREE(def_opts); def_opts = nopts; } else if (*dfl) { def_opts = strealloc(def_opts, dfl); } } XFREE(dflts); /* don't need info vector any more */ if (rvec) XFREE(rvec); return def_opts; }
static am_loc * amfs_lookup_one_location(am_node *new_mp, mntfs *mf, char *ivec, char *def_opts, char *pfname) { am_ops *p; am_opts *fs_opts; am_loc *new_al; mntfs *new_mf; char *mp_dir = NULL; #ifdef HAVE_FS_AUTOFS int on_autofs = 1; #endif /* HAVE_FS_AUTOFS */ /* match the operators */ /* * although we alloc the fs_opts here, the pointer is 'owned' by the am_loc and will * be free'd on destruction of the am_loc. If we don't allocate a loc, then we need * to free this. */ fs_opts = CALLOC(am_opts); p = ops_match(fs_opts, ivec, def_opts, new_mp->am_path, pfname, mf->mf_info); #ifdef HAVE_FS_AUTOFS /* XXX: this should be factored out into an autofs-specific function */ if (new_mp->am_flags & AMF_AUTOFS) { /* ignore user-provided fs if we're using autofs */ if (fs_opts->opt_sublink && fs_opts->opt_sublink[0]) { /* * For sublinks we need to use a hack with autofs: * mount the filesystem on the original opt_fs (which is NOT an * autofs mountpoint) and symlink (or lofs-mount) to it from * the autofs mountpoint. */ on_autofs = 0; mp_dir = fs_opts->opt_fs; } else { if (p->autofs_fs_flags & FS_ON_AUTOFS) { mp_dir = new_mp->am_path; } else { mp_dir = fs_opts->opt_fs; on_autofs = 0; } } } else #endif /* HAVE_FS_AUTOFS */ mp_dir = fs_opts->opt_fs; /* * Find or allocate a filesystem for this node. * we search for a matching backend share, since * we will construct our own al_loc to handle * any customisations for this usage. */ new_mf = find_mntfs(p, fs_opts, mp_dir, fs_opts->fs_mtab, def_opts, fs_opts->opt_opts, fs_opts->opt_remopts); /* * See whether this is a real filesystem */ p = new_mf->mf_ops; if (p == &amfs_error_ops) { plog(XLOG_MAP, "Map entry %s for %s did not match", ivec, new_mp->am_path); free_mntfs(new_mf); free_opts(fs_opts); XFREE(fs_opts); return NULL; } dlog("Got a hit with %s", p->fs_type); new_al = new_loc(); free_mntfs(new_al->al_mnt); new_al->al_mnt = new_mf; new_al->al_fo = fs_opts; /* now the loc is in charge of free'ing this mem */ #ifdef HAVE_FS_AUTOFS if (new_mp->am_flags & AMF_AUTOFS && on_autofs) { new_mf->mf_flags |= MFF_ON_AUTOFS; new_mf->mf_fsflags = new_mf->mf_ops->autofs_fs_flags; } /* * A new filesystem is an autofs filesystems if: * 1. it claims it can be one (has the FS_AUTOFS flag) * 2. autofs is enabled system-wide * 3. either has an autofs parent, * or it is explicitly requested to be autofs. */ if (new_mf->mf_ops->autofs_fs_flags & FS_AUTOFS && amd_use_autofs && ((mf->mf_flags & MFF_IS_AUTOFS) || (new_mf->mf_fo && new_mf->mf_fo->opt_mount_type && STREQ(new_mf->mf_fo->opt_mount_type, "autofs")))) new_mf->mf_flags |= MFF_IS_AUTOFS; #endif /* HAVE_FS_AUTOFS */ return new_al; }
static mntfs * amfs_lookup_one_mntfs(am_node *new_mp, mntfs *mf, char *ivec, char *def_opts, char *pfname) { am_ops *p; am_opts *fs_opts; mntfs *new_mf; char *mp_dir = 0; #ifdef HAVE_FS_AUTOFS int on_autofs = 1; #endif /* HAVE_FS_AUTOFS */ /* match the operators */ fs_opts = CALLOC(am_opts); p = ops_match(fs_opts, ivec, def_opts, new_mp->am_path, pfname, mf->mf_info); #ifdef HAVE_FS_AUTOFS /* XXX: this should be factored out into an autofs-specific function */ if (new_mp->am_flags & AMF_AUTOFS) { /* ignore user-provided fs if we're using autofs */ if (fs_opts->opt_sublink) { /* * For sublinks we need to use a hack with autofs: * mount the filesystem on the original opt_fs (which is NOT an * autofs mountpoint) and symlink (or lofs-mount) to it from * the autofs mountpoint. */ on_autofs = 0; mp_dir = fs_opts->opt_fs; } else { if (p->autofs_fs_flags & FS_ON_AUTOFS) { mp_dir = new_mp->am_path; } else { mp_dir = fs_opts->opt_fs; on_autofs = 0; } } } else #endif /* HAVE_FS_AUTOFS */ mp_dir = fs_opts->opt_fs; /* * Find or allocate a filesystem for this node. */ new_mf = find_mntfs(p, fs_opts, mp_dir, fs_opts->fs_mtab, def_opts, fs_opts->opt_opts, fs_opts->opt_remopts); /* * See whether this is a real filesystem */ p = new_mf->mf_ops; if (p == &amfs_error_ops) { plog(XLOG_MAP, "Map entry %s for %s did not match", ivec, new_mp->am_path); free_mntfs(new_mf); return NULL; } dlog("Got a hit with %s", p->fs_type); #ifdef HAVE_FS_AUTOFS if (new_mp->am_flags & AMF_AUTOFS && on_autofs) { new_mf->mf_flags |= MFF_ON_AUTOFS; new_mf->mf_fsflags = new_mf->mf_ops->autofs_fs_flags; } /* * A new filesystem is an autofs filesystems if: * 1. it claims it can be one (has the FS_AUTOFS flag) * 2. autofs is enabled system-wide * 3. either has an autofs parent, * or it is explicitly requested to be autofs. */ if (new_mf->mf_ops->autofs_fs_flags & FS_AUTOFS && amd_use_autofs && ((mf->mf_flags & MFF_IS_AUTOFS) || (new_mf->mf_fo && new_mf->mf_fo->opt_mount_type && STREQ(new_mf->mf_fo->opt_mount_type, "autofs")))) new_mf->mf_flags |= MFF_IS_AUTOFS; #endif /* HAVE_FS_AUTOFS */ return new_mf; }