static char * amfs_nfsx_match(am_opts *fo) { char *xmtab; char *ptr; int len; if (!fo->opt_rfs) { plog(XLOG_USER, "amfs_nfsx: no remote filesystem specified"); return FALSE; } if (!fo->opt_rhost) { plog(XLOG_USER, "amfs_nfsx: no remote host specified"); return FALSE; } /* set default sublink */ if (fo->opt_sublink == 0) { ptr = strchr(fo->opt_rfs, ','); if (ptr && ptr > (fo->opt_rfs + 1)) fo->opt_sublink = strnsave(fo->opt_rfs + 1, ptr - fo->opt_rfs - 1); } /* * Remove trailing ",..." from ${fs} * After deslashifying, overwrite the end of ${fs} with "/" * to make sure it is unique. */ if ((ptr = strchr(fo->opt_fs, ','))) *ptr = '\0'; deslashify(fo->opt_fs); /* * Bump string length to allow trailing / */ len = strlen(fo->opt_fs); fo->opt_fs = xrealloc(fo->opt_fs, len + 1 + 1); ptr = fo->opt_fs + len; /* * Make unique... */ *ptr++ = '/'; *ptr = '\0'; /* * Determine magic cookie to put in mtab */ xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs); dlog("NFSX: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"", fo->opt_rhost, fo->opt_rfs, fo->opt_fs); return xmtab; }
int eval_fs_opts(am_opts *fo, char *opts, char *g_opts, char *path, char *key, char *map) { int ok = TRUE; free_opts(fo); /* * Clear out the option table */ memset((voidp) &fs_static, 0, sizeof(fs_static)); memset((voidp) vars, 0, sizeof(vars)); memset((voidp) fo, 0, sizeof(*fo)); /* set hostname */ opt_host = (char *) am_get_hostname(); /* * Set key, map & path before expansion */ opt_key = key; opt_map = map; opt_path = path; opt_dkey = strchr(key, '.'); if (!opt_dkey) { opt_dkey = NullStr; opt_keyd = key; } else { opt_keyd = strnsave(key, opt_dkey - key); opt_dkey++; if (*opt_dkey == '\0') /* check for 'host.' */ opt_dkey = NullStr; } /* * Expand global options */ fs_static.fs_glob = expand_selectors(g_opts); /* * Expand local options */ fs_static.fs_local = expand_selectors(opts); /* break global options into fs_static fields */ if ((ok = split_opts(fs_static.fs_glob, key))) { dlog("global split_opts ok"); /* * evaluate local selectors */ if ((ok = eval_selectors(fs_static.fs_local, key))) { dlog("local eval_selectors ok"); /* if the local selectors matched, then do the local overrides */ ok = split_opts(fs_static.fs_local, key); if (ok) dlog("local split_opts ok"); } } /* * Normalize 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 */ if (opt_keyd != key && opt_keyd != nullstr) XFREE(opt_keyd); opt_keyd = nullstr; opt_dkey = NullStr; opt_key = opt_map = opt_path = nullstr; return ok; }
static int amfs_nfsx_init(mntfs *mf) { /* * mf_info has the form: * host:/prefix/path,sub,sub,sub */ int i; int glob_error; struct amfs_nfsx *nx; int asked_for_wakeup = 0; nx = (struct amfs_nfsx *) mf->mf_private; if (nx == 0) { char **ivec; char *info = 0; char *host; char *pref; int error = 0; info = strdup(mf->mf_info); host = strchr(info, ':'); if (!host) { error = EINVAL; goto errexit; } pref = host + 1; host = info; /* * Split the prefix off from the suffices */ ivec = strsplit(pref, ',', '\''); /* * Count array size */ for (i = 0; ivec[i]; i++) /* nothing */; nx = ALLOC(struct amfs_nfsx); mf->mf_private = (opaque_t) nx; mf->mf_prfree = amfs_nfsx_prfree; nx->nx_c = i - 1; /* i-1 because we don't want the prefix */ nx->nx_v = (amfs_nfsx_mnt *) xmalloc(nx->nx_c * sizeof(amfs_nfsx_mnt)); nx->nx_mp = 0; { char *mp = 0; char *xinfo = 0; char *fs = mf->mf_fo->opt_fs; char *rfs = 0; for (i = 0; i < nx->nx_c; i++) { char *path = ivec[i + 1]; rfs = str3cat(rfs, pref, "/", path); /* * Determine the mount point. * If this is the root, then don't remove * the trailing slash to avoid mntfs name clashes. */ mp = str3cat(mp, fs, "/", rfs); normalize_slash(mp); deslashify(mp); /* * Determine the mount info */ xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path); normalize_slash(xinfo); if (pref[1] != '\0') deslashify(xinfo); dlog("amfs_nfsx: init mount for %s on %s", xinfo, mp); nx->nx_v[i].n_error = -1; nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts); /* propagate the on_autofs flag */ nx->nx_v[i].n_mnt->mf_flags |= mf->mf_flags & MFF_ON_AUTOFS; } if (rfs) XFREE(rfs); if (mp) XFREE(mp); if (xinfo) XFREE(xinfo); } XFREE(ivec); errexit: if (info) XFREE(info); if (error) return error; }
static char * nfsx_match(am_opts *fo) { char *xmtab; char *ptr; int len; if (!fo->opt_rfs) { plog(XLOG_USER, "nfsx: no remote filesystem specified"); return FALSE; } if (!fo->opt_rhost) { plog(XLOG_USER, "nfsx: no remote host specified"); return FALSE; } #ifdef notdef /* fiddle sublink, must be last... */ if (fo->opt_sublink) { plog(XLOG_WARNING, "nfsx: sublink %s ignored", fo->opt_sublink); free(fo->opt_sublink); fo->opt_sublink = 0; } #endif /* set default sublink */ if (fo->opt_sublink == 0) { ptr = strchr(fo->opt_rfs, ','); if (ptr && ptr != (fo->opt_rfs + 1)) fo->opt_sublink = strnsave(fo->opt_rfs + 1, ptr - fo->opt_rfs - 1); } /* * Remove trailing ",..." from ${fs} * After deslashifying, overwrite the end of ${fs} with "/" * to make sure it is unique. */ if ((ptr = strchr(fo->opt_fs, ','))) *ptr = '\0'; deslashify(fo->opt_fs); /* * Bump string length to allow trailing / */ len = strlen(fo->opt_fs); if (len > SIZE_MAX - 2) xmallocfailure(); fo->opt_fs = xreallocarray(fo->opt_fs, len + 1 + 1, 1); ptr = fo->opt_fs + len; /* * Make unique... */ *ptr++ = '/'; *ptr = '\0'; /* * Determine magic cookie to put in mtab */ xmtab = str3cat((char *) 0, fo->opt_rhost, ":", fo->opt_rfs); #ifdef DEBUG dlog("NFS: mounting remote server \"%s\", remote fs \"%s\" on \"%s\"", fo->opt_rhost, fo->opt_rfs, fo->opt_fs); #endif /* DEBUG */ return xmtab; }
static int nfsx_init(mntfs *mf) { /* * mf_info has the form: * host:/prefix/path,sub,sub,sub */ int i; int glob_error; struct nfsx *nx; int asked_for_wakeup = 0; nx = (struct nfsx *) mf->mf_private; if (nx == 0) { char **ivec; char *info = 0; char *host; char *pref; int error = 0; info = strdup(mf->mf_info); host = strchr(info, ':'); if (!host) { error = EINVAL; goto errexit; } pref = host+1; host = info; /* * Split the prefix off from the suffices */ ivec = strsplit(pref, ',', '\''); /* * Count array size */ for (i = 0; ivec[i]; i++) ; nx = ALLOC(nfsx); mf->mf_private = nx; mf->mf_prfree = nfsx_prfree; nx->nx_c = i - 1; /* i-1 because we don't want the prefix */ nx->nx_v = xreallocarray(NULL, nx->nx_c, sizeof *nx->nx_v); { char *mp = 0; char *xinfo = 0; char *fs = mf->mf_fo->opt_fs; char *rfs = 0; for (i = 0; i < nx->nx_c; i++) { char *path = ivec[i+1]; rfs = str3cat(rfs, pref, "/", path); /* * Determine the mount point. * If this is the root, then don't remove * the trailing slash to avoid mntfs name clashes. */ mp = str3cat(mp, fs, "/", rfs); normalize_slash(mp); deslashify(mp); /* * Determine the mount info */ xinfo = str3cat(xinfo, host, *path == '/' ? "" : "/", path); normalize_slash(xinfo); if (pref[1] != '\0') deslashify(xinfo); #ifdef DEBUG dlog("nfsx: init mount for %s on %s", xinfo, mp); #endif nx->nx_v[i].n_error = -1; nx->nx_v[i].n_mnt = find_mntfs(&nfs_ops, mf->mf_fo, mp, xinfo, "", mf->mf_mopts, mf->mf_remopts); } free(rfs); free(mp); free(xinfo); } free(ivec); errexit: free(info); if (error) return error; } /* * Iterate through the mntfs's and call * the underlying init routine on each */ glob_error = 0; for (i = 0; i < nx->nx_c; i++) { nfsx_mnt *n = &nx->nx_v[i]; mntfs *m = n->n_mnt; int error = (*m->mf_ops->fs_init)(m); /* * If HARD_NFSX_ERRORS is defined, make any * initialisation failure a hard error and * fail the entire group. Otherwise only fail * if none of the group is mountable (see nfsx_fmount). */ #ifdef HARD_NFSX_ERRORS if (error > 0) return error; #else if (error > 0) n->n_error = error; #endif else if (error < 0) { glob_error = -1; if (!asked_for_wakeup) { asked_for_wakeup = 1; sched_task(wakeup_task, mf, m); } } } return glob_error; }