/*
 * 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);
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}