예제 #1
0
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;
}
예제 #2
0
파일: opts.c 프로젝트: AzerTyQsdF/osx
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;
}
예제 #3
0
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;
  }
예제 #4
0
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;
}
예제 #5
0
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;
}