Exemplo n.º 1
0
/*
 * return string option which is the reverse of opt.
 * nosuid -> suid
 * quota -> noquota
 * ro -> rw
 * etc.
 * may return pointer to static buffer or subpointer within opt.
 */
static char *
reverse_option(const char *opt)
{
  static char buf[80];

  /* sanity check */
  if (!opt)
    return NULL;

  /* check special cases */
  /* XXX: if this gets too long, rewrite the code more flexibly */
  if (STREQ(opt, "ro")) return "rw";
  if (STREQ(opt, "rw")) return "ro";
  if (STREQ(opt, "bg")) return "fg";
  if (STREQ(opt, "fg")) return "bg";
  if (STREQ(opt, "soft")) return "hard";
  if (STREQ(opt, "hard")) return "soft";

  /* check if string starts with 'no' and chop it */
  if (NSTREQ(opt, "no", 2)) {
    xstrlcpy(buf, &opt[2], sizeof(buf));
  } else {
    /* finally return a string prepended with 'no' */
    xstrlcpy(buf, "no", sizeof(buf));
    xstrlcat(buf, opt, sizeof(buf));
  }
  return buf;
}
Exemplo n.º 2
0
/* convert from ix386 mnttab to amd mntent */
static mntent_t *
mnt_dup(mntent_t *mp)
{
  /* note: may not be null terminated */
  mntent_t *new_mp = ALLOC(mntent_t);
  char nullcpy[128];

  xstrlcpy(nullcpy, mp->mt_dev, 32);
  new_mp->mnt_fsname = strdup(nullcpy);

  xstrlcpy(nullcpy, mp->mt_filsys, 32);
  new_mp->mnt_dir = strdup(nullcpy);

  xstrlcpy(nullcpy, mp->mt_fstyp, 16);
  new_mp->mnt_type = strdup(nullcpy);

  xstrlcpy(nullcpy, mp->mt_mntopts, 64);
  new_mp->mnt_opts = strdup(nullcpy);

  new_mp->mnt_freq = 0;
  new_mp->mnt_passno = 0;

  new_mp->mnt_time = mp->mt_time;
  new_mp->mnt_ro = mp->mt_ro_flg;

  return new_mp;
}
Exemplo n.º 3
0
/*
 * Take a little-endian domain name and
 * transform into a big-endian Un*x pathname.
 * For example: kiska.doc.ic -> ic/doc/kiska
 */
static char *
compute_hostpath(char *hn)
{
  char *p = xmalloc(MAXPATHLEN);
  char *d;
  char path[MAXPATHLEN];

  xstrlcpy(p, hn, MAXPATHLEN);
  domain_strip(p, hostname);
  path[0] = '\0';

  do {
    d = strrchr(p, '.');
    if (d) {
      *d = 0;
      xstrlcat(path, d + 1, sizeof(path));
      xstrlcat(path, "/", sizeof(path));
    } else {
      xstrlcat(path, p, sizeof(path));
    }
  } while (d);

  fsi_log("hostpath of '%s' is '%s'", hn, path);

  xstrlcpy(p, path, MAXPATHLEN);
  return p;
}
Exemplo n.º 4
0
Arquivo: env.c Projeto: phodge/neovim
/// Gets the hostname of the current machine.
///
/// @param hostname   Buffer to store the hostname.
/// @param size       Size of `hostname`.
void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
  struct utsname vutsname;

  if (uname(&vutsname) < 0) {
    *hostname = '\0';
  } else {
    xstrlcpy(hostname, vutsname.nodename, size);
  }
#elif defined(WIN32)
  wchar_t host_utf16[MAX_COMPUTERNAME_LENGTH + 1];
  DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]);
  if (GetComputerNameW(host_utf16, &host_wsize) == 0) {
    *hostname = '\0';
    DWORD err = GetLastError();
    EMSG2("GetComputerNameW failed: %d", err);
    return;
  }
  host_utf16[host_wsize] = '\0';

  char *host_utf8;
  int conversion_result = utf16_to_utf8(host_utf16, &host_utf8);
  if (conversion_result != 0) {
    EMSG2("utf16_to_utf8 failed: %d", conversion_result);
    return;
  }
  xstrlcpy(hostname, host_utf8, size);
  xfree(host_utf8);
#else
  EMSG("os_get_hostname failed: missing uname()");
  *hostname = '\0';
#endif
}
Exemplo n.º 5
0
int
main(int argc, char *argv[])
{
	int		 ch;
	char		*aux, *base, *conf_file;
	struct manpaths	 dirs;
	char		 buf[MAXPATHLEN];
	extern char	*optarg;
	extern int	 optind;

	progname = strrchr(argv[0], '/');
	if (progname == NULL)
		progname = argv[0];
	else
		++progname;

	aux = base = conf_file = NULL;
	xstrlcpy(buf, "/var/www/cache/man.cgi", MAXPATHLEN);

	while (-1 != (ch = getopt(argc, argv, "C:fm:M:o:v")))
		switch (ch) {
		case ('C'):
			conf_file = optarg;
			break;
		case ('f'):
			force = 1;
			break;
		case ('m'):
			aux = optarg;
			break;
		case ('M'):
			base = optarg;
			break;
		case ('o'):
			xstrlcpy(buf, optarg, MAXPATHLEN);
			break;
		case ('v'):
			verbose++;
			break;
		default:
			usage();
			return(EXIT_FAILURE);
		}

	argc -= optind;
	argv += optind;

	if (argc > 0) {
		usage();
		return(EXIT_FAILURE);
	}

	memset(&dirs, 0, sizeof(struct manpaths));
	manpath_parse(&dirs, conf_file, base, aux);
	ch = manup(&dirs, buf);
	manpath_free(&dirs);
	return(ch ? EXIT_SUCCESS : EXIT_FAILURE);
}
Exemplo n.º 6
0
/*
 * Update the destination's file-tree with respect to changes in the
 * source manpath components.
 * "Change" is defined by an updated index or btree database.
 * Returns 1 on success, 0 on failure.
 */
static int
manup(const struct manpaths *dirs, char *base)
{
	char		 dst[MAXPATHLEN],
			 src[MAXPATHLEN];
	const char	*path;
	int		 i, c;
	size_t		 sz;
	FILE		*f;

	/* Create the path and file for the catman.conf file. */

	sz = strlen(base);
	xstrlcpy(dst, base, MAXPATHLEN);
	xstrlcat(dst, "/etc", MAXPATHLEN);
	if (-1 == mkpath(dst, 0755, 0755)) {
		perror(dst);
		return(0);
	}

	xstrlcat(dst, "/catman.conf", MAXPATHLEN);
	if (NULL == (f = fopen(dst, "w"))) {
		perror(dst);
		return(0);
	} else if (verbose)
		printf("%s\n", dst);

	for (i = 0; i < dirs->sz; i++) {
		path = dirs->paths[i];
		dst[(int)sz] = '\0';
		xstrlcat(dst, path, MAXPATHLEN);
		if (-1 == mkpath(dst, 0755, 0755)) {
			perror(dst);
			break;
		}

		xstrlcpy(src, path, MAXPATHLEN);
		if (-1 == (c = treecpy(dst, src)))
			break;
		else if (0 == c)
			continue;

		/*
		 * We want to use a relative path here because manpath.h
		 * will realpath() when invoked with man.cgi, and we'll
		 * make sure to chdir() into the cache directory before.
		 *
		 * This allows the cache directory to be in an arbitrary
		 * place, working in both chroot() and non-chroot()
		 * "safe" modes.
		 */
		assert('/' == path[0]);
		fprintf(f, "_whatdb %s/whatis.db\n", path + 1);
	}

	fclose(f);
	return(i == dirs->sz);
}
Exemplo n.º 7
0
/*
 * start with an empty string. for each opts1 option that is not
 * in opts2, add it to the string (make sure the reverse of it
 * isn't in either). finally add opts2. return new string.
 * Both opts1 and opts2 must not be null!
 * Caller must eventually free the string being returned.
 */
static char *
merge_opts(const char *opts1, const char *opts2)
{
  mntent_t mnt2;		/* place holder for opts2 */
  char *newstr;			/* new string to return (malloc'ed) */
  char *tmpstr;			/* temp */
  char *eq;			/* pointer to whatever follows '=' within temp */
  char oneopt[80];		/* one option w/o value if any */
  char *revoneopt;		/* reverse of oneopt */
  size_t len = strlen(opts1) + strlen(opts2) + 2; /* space for "," and NULL */
  char *s1 = strdup(opts1);	/* copy of opts1 to munge */

  /* initialization */
  mnt2.mnt_opts = (char *) opts2;
  newstr = xmalloc(len);
  newstr[0] = '\0';

  for (tmpstr = strtok(s1, ",");
       tmpstr;
       tmpstr = strtok(NULL, ",")) {
    /* copy option to temp buffer */
    xstrlcpy(oneopt, tmpstr, sizeof(oneopt));
    /* if option has a value such as rsize=1024, chop the value part */
    if ((eq = haseq(oneopt)))
      *eq = '\0';
    /* find reverse option of oneopt */
    revoneopt = reverse_option(oneopt);
    /* if option orits reverse exist in opts2, ignore it */
    if (amu_hasmntopt(&mnt2, oneopt) || amu_hasmntopt(&mnt2, revoneopt))
      continue;
    /* add option to returned string */
    if (newstr[0]) {
      xstrlcat(newstr, ",", len);
      xstrlcat(newstr, tmpstr, len);
    } else {
      xstrlcpy(newstr, tmpstr, len);
    }
  }

  /* finally, append opts2 itself */
  if (newstr[0]) {
    xstrlcat(newstr, ",", len);
    xstrlcat(newstr, opts2, len);
  } else {
    xstrlcpy(newstr, opts2, len);
  }

  XFREE(s1);
  return newstr;
}
Exemplo n.º 8
0
/*
 * The routine transform_dir(path) transforms pathnames of directories
 * mounted with the amd automounter to produce a more "natural" version.
 * The automount table is obtained from the local amd via the rpc interface
 * and reverse lookups are repeatedly performed on the directory name
 * substituting the name of the automount link for the value of the link
 * whenever it occurs as a prefix of the directory name.
 */
static char *
transform_dir(char *dir)
{
#ifdef DISK_HOME_HACK
  char *ch;
#endif /* DISK_HOME_HACK */
  char *server;
  struct sockaddr_in server_addr;
  int s = RPC_ANYSOCK;
  CLIENT *clnt;
  struct hostent *hp;
  struct timeval tmo = {10, 0};
  char *dummystr;
  amq_string *spp;

#ifdef DISK_HOME_HACK
  if (ch = hack_name(dir))
    return ch;
#endif /* DISK_HOME_HACK */

#ifdef HAVE_CNODEID
  server = cluster_server();
#else /* not HAVE_CNODEID */
  server = localhost;
#endif /* not HAVE_CNODEID */

  if ((hp = gethostbyname(server)) == NULL)
    return dir;
  memset(&server_addr, 0, sizeof(server_addr));
  /* as per POSIX, sin_len need not be set (used internally by kernel) */
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr = *(struct in_addr *) hp->h_addr;

  clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s);
  if (clnt == NULL)
    clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0);
  if (clnt == NULL)
    return dir;

  xstrlcpy(transform, dir, sizeof(transform));
  dummystr = transform;
  spp = amqproc_pawd_1((amq_string *) &dummystr, clnt);
  if (spp && *spp && **spp) {
    xstrlcpy(transform, *spp, sizeof(transform));
    XFREE(*spp);
  }
  clnt_destroy(clnt);
  return transform;
}
Exemplo n.º 9
0
int
ndbm_init(mnt_map *m, char *map, time_t *tp)
{
  DBM *db;

  db = dbm_open(map, O_RDONLY, 0);
  if (db) {
    struct stat stb;
    int error;
#ifdef DBM_SUFFIX
    char dbfilename[256];

    xstrlcpy(dbfilename, map, sizeof(dbfilename));
    xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
    error = stat(dbfilename, &stb);
#else /* not DBM_SUFFIX */
    error = fstat(dbm_pagfno(db), &stb);
#endif /* not DBM_SUFFIX */
    if (error < 0)
      *tp = clocktime(NULL);
    else
      *tp = stb.st_mtime;
    dbm_close(db);
    return 0;
  }
  return errno;
}
Exemplo n.º 10
0
int
ndbm_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
{
  DBM *db;

  db = dbm_open(map, O_RDONLY, 0);
  if (db) {
    struct stat stb;
    int error;
#ifdef DBM_SUFFIX
    char dbfilename[256];

    xstrlcpy(dbfilename, map, sizeof(dbfilename));
    xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
    error = stat(dbfilename, &stb);
#else /* not DBM_SUFFIX */
    error = fstat(dbm_pagfno(db), &stb);
#endif /* not DBM_SUFFIX */
    if (!error && *tp < stb.st_mtime) {
      *tp = stb.st_mtime;
      error = -1;
    } else {
      error = search_ndbm(m, db, key, pval);
    }
    (void) dbm_close(db);
    return error;
  }
  return errno;
}
Exemplo n.º 11
0
static mntent_t *
mnt_dup(struct statfs *mp)
{
  mntent_t *new_mp = ALLOC(mntent_t);
  char *ty;
  char *at;
  char mntfrombuf[MNAMELEN];
  char *mntfromptr;

  /*
   * Under DEC OSF/1 T1.2-2 the f_mntfromname fields of
   * the statfs structure can be in the format <fs>@<host>
   * instead of <host>:<fs>.  Here we check for this and
   * reformat it if necessary.
   */
  mntfromptr = mp->f_mntfromname;

  switch (mp->f_type) {
  case MOUNT_TYPE_NFS:
#ifdef HAVE_FS_NFS3
  case MOUNT_TYPE_NFS3:
#endif /* HAVE_FS_NFS3 */
    at = strchr(mp->f_mntfromname, '@');
    if (at != '\0') {
      xstrlcpy(mntfrombuf, (at + 1), sizeof(mntfrombuf));
      xstrlcat(mntfrombuf, ":", sizeof(mntfrombuf));
      strncat(mntfrombuf, mp->f_mntfromname, (at - mp->f_mntfromname));
      mntfromptr = mntfrombuf;
    }
  }
  new_mp->mnt_fsname = strdup(mntfromptr);

  new_mp->mnt_dir = strdup(mp->f_mntonname);
  switch (mp->f_type) {
  case MOUNT_TYPE_UFS:
    ty = MNTTAB_TYPE_UFS;
    break;
#ifdef HAVE_FS_NFS3
  case MOUNT_TYPE_NFS3:
    ty = MNTTAB_TYPE_NFS3;
    break;
#endif /* HAVE_FS_NFS3 */
  case MOUNT_TYPE_NFS:
    ty = MNTTAB_TYPE_NFS;
    break;
  case MOUNT_TYPE_MFS:
    ty = MNTTAB_TYPE_MFS;
    break;
  default:
    ty = "unknown";
    break;
  }

  new_mp->mnt_type = strdup(ty);
  new_mp->mnt_opts = strdup("unset");
  new_mp->mnt_freq = 0;
  new_mp->mnt_passno = 0;

  return new_mp;
}
Exemplo n.º 12
0
/* convert back (static alloc) */
static mntent_t *
mtab_of(mntent_t *mnt)
{
  static mntent_t mt;

  xstrlcpy(mt.mt_dev, mnt->mnt_fsname, 32);
  xstrlcpy(mt.mt_filsys, mnt->mnt_dir, 32);

  mt.mt_ro_flg = mnt->mnt_ro;
  mt.mt_time = mnt->mnt_time;

  xstrlcpy(mt.mt_fstyp, mnt->mnt_type, 16);
  xstrlcpy(mt.mt_mntopts, mnt->mnt_opts, 64);

  return &mt;
}
Exemplo n.º 13
0
Arquivo: xutil.c Projeto: 0mp/freebsd
/*
 * Take a log format string and expand occurrences of %m
 * with the current error code taken from errno.  Make sure
 * 'e' never gets longer than maxlen characters.
 */
static const char *
expand_error(const char *f, char *e, size_t maxlen)
{
  const char *p;
  char *q;
  int error = errno;
  size_t len = 0, l;

  *e = '\0';
  for (p = f, q = e; len < maxlen && (*q = *p); len++, q++, p++) {
    if (p[0] == '%' && p[1] == 'm') {
      if (len >= maxlen)
	break;
      xstrlcpy(q, strerror(error), maxlen - len);
      l = strlen(q);
      if (l != 0)
	  l--;
      len += l;
      q += l;
      p++;
    }
  }
  e[maxlen - 1] = '\0';		/* null terminate, to be sure */
  return e;
}
Exemplo n.º 14
0
/*
 * Process PAWD string of remote pawd tool.
 *
 * We repeat the resolution of the string until the resolved string resolves
 * to itself.  This ensures that we follow path resolutions through all
 * possible Amd mount points until we reach some sort of convergence.  To
 * prevent possible infinite loops, we break out of this loop if the strings
 * do not converge after MAX_PAWD_TRIES times.
 */
amq_string *
amqproc_pawd_1_svc(voidp argp, struct svc_req *rqstp)
{
  static amq_string res;
#define MAX_PAWD_TRIES 10
  int index, len, maxagain = MAX_PAWD_TRIES;
  am_node *mp;
  char *mountpoint;
  char *dir = *(char **) argp;
  static char tmp_buf[MAXPATHLEN];
  char prev_buf[MAXPATHLEN];

  tmp_buf[0] = prev_buf[0] = '\0'; /* default is empty string: no match */
  do {
    for (mp = get_first_exported_ap(&index);
	 mp;
	 mp = get_next_exported_ap(&index)) {
      if (STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "toplvl"))
	continue;
      if (STREQ(mp->am_al->al_mnt->mf_ops->fs_type, "auto"))
	continue;
      mountpoint = (mp->am_link ? mp->am_link : mp->am_al->al_mnt->mf_mount);
      len = strlen(mountpoint);
      if (len == 0)
	continue;
      if (!NSTREQ(mountpoint, dir, len))
	continue;
      if (dir[len] != '\0' && dir[len] != '/')
	continue;
      xstrlcpy(tmp_buf, mp->am_path, sizeof(tmp_buf));
      xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf));
      break;
    } /* end of "for" loop */
    /* once tmp_buf and prev_buf are equal, break out of "do" loop */
    if (STREQ(tmp_buf, prev_buf))
      break;
    else
      xstrlcpy(prev_buf, tmp_buf, sizeof(prev_buf));
  } while (--maxagain);
  /* check if we couldn't resolve the string after MAX_PAWD_TRIES times */
  if (maxagain <= 0)
    plog(XLOG_WARNING, "path \"%s\" did not resolve after %d tries",
	 tmp_buf, MAX_PAWD_TRIES);

  res = tmp_buf;
  return &res;
}
Exemplo n.º 15
0
/*
 * Display a pwd data
 */
static void
show_pwd(amq_mount_tree *mt, char *path, size_t l, int *flag)
{
  int len;

  while (mt) {
    len = strlen(mt->mt_mountpoint);
    if (NSTREQ(path, mt->mt_mountpoint, len) &&
	!STREQ(mt->mt_directory, mt->mt_mountpoint)) {
      char buf[MAXPATHLEN+1];	/* must be same size as 'path' */
      xstrlcpy(buf, mt->mt_directory, sizeof(buf));
      xstrlcat(buf, &path[len], sizeof(buf));
      xstrlcpy(path, buf, l);
      *flag = 1;
    }
    show_pwd(mt->mt_next, path, l, flag);
    mt = mt->mt_child;
  }
}
Exemplo n.º 16
0
/* getawd() is a substitute for getwd() which transforms the path */
static char *
getawd(char *path, size_t l)
{
#ifdef HAVE_GETCWD
  char *wd = getcwd(path, MAXPATHLEN);
#else /* not HAVE_GETCWD */
  char *wd = getwd(path);
#endif /* not HAVE_GETCWD */

  if (wd == NULL) {
    return NULL;
  }
  xstrlcpy(path, transform_dir(wd), l);
  return path;
}
Exemplo n.º 17
0
int
autofs_get_fh(am_node *mp)
{
    autofs_fh_t *fh;
    char buf[MAXHOSTNAMELEN];
    mntfs *mf = mp->am_al->al_mnt;
    struct utsname utsname;

    plog(XLOG_DEBUG, "autofs_get_fh for %s", mp->am_path);
    fh = ALLOC(autofs_fh_t);
    memset((voidp) fh, 0, sizeof(autofs_fh_t)); /* Paranoid */

    /*
     * SET MOUNT ARGS
     */
    if (uname(&utsname) < 0) {
        xstrlcpy(buf, "localhost.autofs", sizeof(buf));
    } else {
        xstrlcpy(buf, utsname.nodename, sizeof(buf));
        xstrlcat(buf, ".autofs", sizeof(buf));
    }
#ifdef HAVE_AUTOFS_ARGS_T_ADDR
    fh->addr.buf = xstrdup(buf);
    fh->addr.len = fh->addr.maxlen = strlen(buf);
#endif /* HAVE_AUTOFS_ARGS_T_ADDR */

    fh->direct = (mf->mf_fsflags & FS_DIRECT) ? 1 : 0;
    fh->rpc_to = 1;		/* XXX: arbitrary */
    fh->mount_to = mp->am_timeo;
    fh->path = mp->am_path;
    fh->opts = "";		/* XXX: arbitrary */
    fh->map = mp->am_path;	/* this is what we get back in readdir */

    mp->am_autofs_fh = fh;
    return 0;
}
Exemplo n.º 18
0
Arquivo: autil.c Projeto: 0mp/freebsd
/*
 * Copy s into p, reallocating p if necessary
 */
char *
strealloc(char *p, char *s)
{
  size_t len = strlen(s) + 1;

  p = (char *) xrealloc((voidp) p, len);

  xstrlcpy(p, s, len);
#ifdef DEBUG_MEM
# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY)
  malloc_verify();
# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */
#endif /* DEBUG_MEM */
  return p;
}
Exemplo n.º 19
0
/*
 * replacement for hasmntopt if the system does not have it.
 */
char *
amu_hasmntopt(mntent_t *mnt, char *opt)
{
  char t[MNTMAXSTR];
  char *f;
  char *o = t;
  size_t l = strlen(opt);

  xstrlcpy(t, mnt->mnt_opts, sizeof(t));

  while (*(f = nextmntopt(&o)))
    if (NSTREQ(opt, f, l))
      return f - t + mnt->mnt_opts;

  return 0;
}
Exemplo n.º 20
0
/*
 * Determine the mount point:
 *
 * The next change we put in to better handle PCs.  This is a bit
 * disgusting, so you'd better sit down.  We change the make_mntpt function
 * to look for exported file systems without a leading '/'.  If they don't
 * have a leading '/', we add one.  If the export is 'a:' through 'z:'
 * (without a leading slash), we change it to 'a%' (or b% or z%).  This
 * allows the entire PC disk to be mounted.
 */
static void
make_mntpt(char *mntpt, size_t l, const exports ex, const char *mf_mount)
{
  if (ex->ex_dir[0] == '/') {
    if (ex->ex_dir[1] == 0)
      xstrlcpy(mntpt, mf_mount, l);
    else
      xsnprintf(mntpt, l, "%s%s", mf_mount, ex->ex_dir);
  } else if (ex->ex_dir[0] >= 'a' &&
	     ex->ex_dir[0] <= 'z' &&
	     ex->ex_dir[1] == ':' &&
	     ex->ex_dir[2] == '/' &&
	     ex->ex_dir[3] == 0)
    xsnprintf(mntpt, l, "%s/%c%%", mf_mount, ex->ex_dir[0]);
  else
    xsnprintf(mntpt, l, "%s/%s", mf_mount, ex->ex_dir);
}
Exemplo n.º 21
0
/* return malloc'ed buffer.  caller must free it */
char *
print_wires(void)
{
  addrlist *al;
  char s[256];
  int i;
  char *buf;
  int bufcount = 0;
  int buf_size = 1024;

  buf = SALLOC(buf_size);	/* initial allocation (may grow!) */
  if (!buf)
    return NULL;

  if (!localnets) {
    xstrlcpy(buf, "No networks\n", buf_size);
    return buf;
  }
  /* check if there's more than one network */
  if (!localnets->ip_next) {
    /* use buf_size for sizeof(buf) because of the realloc() below */
    xsnprintf(buf, buf_size,
	      "Network: wire=\"%s\" (netnumber=%s).\n",
	      localnets->ip_net_name, localnets->ip_net_num);
    return buf;
  }
  buf[0] = '\0';		/* null out buffer before appending */
  for (i = 1, al = localnets; al; al = al->ip_next, i++) {
    xsnprintf(s, sizeof(s), "Network %d: wire=\"%s\" (netnumber=%s).\n",
	      i, al->ip_net_name, al->ip_net_num);
    bufcount += strlen(s);
    if (bufcount > buf_size) {
      buf_size *= 2;
      buf = xrealloc(buf, buf_size);
    }
    xstrlcat(buf, s, buf_size);
  }
  return buf;
}
Exemplo n.º 22
0
void
fatal(char *mess)
{
  if (logfile && !STREQ(logfile, "stderr")) {
    char lessmess[128];
    int messlen;

    messlen = strlen(mess);

    if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM))
      fprintf(stderr, "%s: %s\n", am_get_progname(), mess);
    else {
      xstrlcpy(lessmess, mess, sizeof(lessmess));
      lessmess[messlen - 4] = '\0';

      fprintf(stderr, "%s: %s: %s\n",
	      am_get_progname(), lessmess, strerror(errno));
    }
  }
  plog(XLOG_FATAL, "%s", mess);

  hlfsd_going_down(1);
}
Exemplo n.º 23
0
/// End try block, set the error message if any and return true if an error
/// occurred.
///
/// @param err Pointer to the stack-allocated error object
/// @return true if an error occurred
bool try_end(Error *err)
{
    --trylevel;

    // Without this it stops processing all subsequent VimL commands and
    // generates strange error messages if I e.g. try calling Test() in a
    // cycle
    did_emsg = false;

    if (got_int) {
        if (did_throw) {
            // If we got an interrupt, discard the current exception
            discard_current_exception();
        }

        api_set_error(err, Exception, _("Keyboard interrupt"));
        got_int = false;
    } else if (msg_list != NULL && *msg_list != NULL) {
        int should_free;
        char *msg = (char *)get_exception_string(*msg_list,
                    ET_ERROR,
                    NULL,
                    &should_free);
        xstrlcpy(err->msg, msg, sizeof(err->msg));
        err->set = true;
        free_global_msglist();

        if (should_free) {
            xfree(msg);
        }
    } else if (did_throw) {
        api_set_error(err, Exception, "%s", current_exception->value);
        discard_current_exception();
    }

    return err->set;
}
Exemplo n.º 24
0
static int
amfs_host_mount(am_node *am, mntfs *mf)
{
  struct timeval tv2;
  CLIENT *client;
  enum clnt_stat clnt_stat;
  int n_export;
  int j, k;
  exports exlist = 0, ex;
  exports *ep = NULL;
  am_nfs_handle_t *fp = NULL;
  char *host;
  int error = 0;
  struct sockaddr_in sin;
  int sock = RPC_ANYSOCK;
  int ok = FALSE;
  mntlist *mlist;
  char fs_name[MAXPATHLEN], *rfs_dir;
  char mntpt[MAXPATHLEN];
  struct timeval tv;
  u_long mnt_version;

  /*
   * WebNFS servers don't necessarily run mountd.
   */
  if (mf->mf_flags & MFF_WEBNFS) {
    plog(XLOG_ERROR, "amfs_host_mount: cannot support WebNFS");
    return EIO;
  }

  /*
   * Read the mount list
   */
  mlist = read_mtab(mf->mf_mount, mnttab_file_name);

#ifdef MOUNT_TABLE_ON_FILE
  /*
   * Unlock the mount list
   */
  unlock_mntlist();
#endif /* MOUNT_TABLE_ON_FILE */

  /*
   * Take a copy of the server hostname, address, and nfs version
   * to mount version conversion.
   */
  host = mf->mf_server->fs_host;
  sin = *mf->mf_server->fs_ip;
  plog(XLOG_INFO, "amfs_host_mount: NFS version %d", (int) mf->mf_server->fs_version);
#ifdef HAVE_FS_NFS3
  if (mf->mf_server->fs_version == NFS_VERSION3)
    mnt_version = AM_MOUNTVERS3;
  else
#endif /* HAVE_FS_NFS3 */
    mnt_version = MOUNTVERS;

  /*
   * The original 10 second per try timeout is WAY too large, especially
   * if we're only waiting 10 or 20 seconds max for the response.
   * That would mean we'd try only once in 10 seconds, and we could
   * lose the transmit or receive packet, and never try again.
   * A 2-second per try timeout here is much more reasonable.
   * 09/28/92 Mike Mitchell, [email protected]
   */
  tv.tv_sec = 2;
  tv.tv_usec = 0;

  /*
   * Create a client attached to mountd
   */
  client = get_mount_client(host, &sin, &tv, &sock, mnt_version);
  if (client == NULL) {
#ifdef HAVE_CLNT_SPCREATEERROR
    plog(XLOG_ERROR, "get_mount_client failed for %s: %s",
	 host, clnt_spcreateerror(""));
#else /* not HAVE_CLNT_SPCREATEERROR */
    plog(XLOG_ERROR, "get_mount_client failed for %s", host);
#endif /* not HAVE_CLNT_SPCREATEERROR */
    error = EIO;
    goto out;
  }
  if (!nfs_auth) {
    error = make_nfs_auth();
    if (error)
      goto out;
  }
  client->cl_auth = nfs_auth;

  dlog("Fetching export list from %s", host);

  /*
   * Fetch the export list
   */
  tv2.tv_sec = 10;
  tv2.tv_usec = 0;
  clnt_stat = clnt_call(client,
			MOUNTPROC_EXPORT,
			(XDRPROC_T_TYPE) xdr_void,
			0,
			(XDRPROC_T_TYPE) xdr_exports,
			(SVC_IN_ARG_TYPE) & exlist,
			tv2);
  if (clnt_stat != RPC_SUCCESS) {
    const char *msg = clnt_sperrno(clnt_stat);
    plog(XLOG_ERROR, "host_mount rpc failed: %s", msg);
    /* clnt_perror(client, "rpc"); */
    error = EIO;
    goto out;
  }

  /*
   * Figure out how many exports were returned
   */
  for (n_export = 0, ex = exlist; ex; ex = ex->ex_next) {
    n_export++;
  }

  /*
   * Allocate an array of pointers into the list
   * so that they can be sorted.  If the filesystem
   * is already mounted then ignore it.
   */
  ep = (exports *) xmalloc(n_export * sizeof(exports));
  for (j = 0, ex = exlist; ex; ex = ex->ex_next) {
    make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
    if (already_mounted(mlist, mntpt))
      /* we have at least one mounted f/s, so don't fail the mount */
      ok = TRUE;
    else
      ep[j++] = ex;
  }
  n_export = j;

  /*
   * Sort into order.
   * This way the mounts are done in order down the tree,
   * instead of any random order returned by the mount
   * daemon (the protocol doesn't specify...).
   */
  qsort(ep, n_export, sizeof(exports), sortfun);

  /*
   * Allocate an array of filehandles
   */
  fp = (am_nfs_handle_t *) xmalloc(n_export * sizeof(am_nfs_handle_t));

  /*
   * Try to obtain filehandles for each directory.
   * If a fetch fails then just zero out the array
   * reference but discard the error.
   */
  for (j = k = 0; j < n_export; j++) {
    /* Check and avoid a duplicated export entry */
    if (j > k && ep[k] && STREQ(ep[j]->ex_dir, ep[k]->ex_dir)) {
      dlog("avoiding dup fhandle requested for %s", ep[j]->ex_dir);
      ep[j] = NULL;
    } else {
      k = j;
      error = fetch_fhandle(client, ep[j]->ex_dir, &fp[j],
			    mf->mf_server->fs_version);
      if (error)
	ep[j] = NULL;
    }
  }

  /*
   * Mount each filesystem for which we have a filehandle.
   * If any of the mounts succeed then mark "ok" and return
   * error code 0 at the end.  If they all fail then return
   * the last error code.
   */
  xstrlcpy(fs_name, mf->mf_info, sizeof(fs_name));
  if ((rfs_dir = strchr(fs_name, ':')) == (char *) NULL) {
    plog(XLOG_FATAL, "amfs_host_mount: mf_info has no colon");
    error = EINVAL;
    goto out;
  }
  ++rfs_dir;
  for (j = 0; j < n_export; j++) {
    ex = ep[j];
    if (ex) {
      /*
       * Note: the sizeof space left in rfs_dir is what's left in fs_name
       * after strchr() above returned a pointer _inside_ fs_name.  The
       * calculation below also takes into account that rfs_dir was
       * incremented by the ++ above.
       */
      xstrlcpy(rfs_dir, ex->ex_dir, sizeof(fs_name) - (rfs_dir - fs_name));
      make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
      if (do_mount(&fp[j], mntpt, fs_name, mf) == 0)
	ok = TRUE;
    }
  }

  /*
   * Clean up and exit
   */
out:
  discard_mntlist(mlist);
  XFREE(ep);
  XFREE(fp);
  if (sock != RPC_ANYSOCK)
    (void) amu_close(sock);
  if (client)
    clnt_destroy(client);
  if (exlist)
    xdr_pri_free((XDRPROC_T_TYPE) xdr_exports, (caddr_t) &exlist);
  if (ok)
    return 0;
  return error;
}
Exemplo n.º 25
0
int
main(int argc, char *argv[])
{
  char *domdot, *verstr, *vertmp;
  int ppid = 0;
  int error;
  char *progname = NULL;		/* "amd" */
  char hostname[MAXHOSTNAMELEN + 1] = "localhost"; /* Hostname */

  /*
   * Make sure some built-in assumptions are true before we start
   */
  assert(sizeof(nfscookie) >= sizeof(u_int));
  assert(sizeof(int) >= 4);

  /*
   * Set processing status.
   */
  amd_state = Start;

  /*
   * Determine program name
   */
  if (argv[0]) {
    progname = strrchr(argv[0], '/');
    if (progname && progname[1])
      progname++;
    else
      progname = argv[0];
  }
  if (!progname)
    progname = "amd";
  am_set_progname(progname);

  /*
   * Initialize process id.  This is kept
   * cached since it is used for generating
   * and using file handles.
   */
  am_set_mypid();

  /*
   * Get local machine name
   */
  if (gethostname(hostname, sizeof(hostname)) < 0) {
    plog(XLOG_FATAL, "gethostname: %m");
    going_down(1);
  }
  hostname[sizeof(hostname) - 1] = '\0';

  /*
   * Check it makes sense
   */
  if (!*hostname) {
    plog(XLOG_FATAL, "host name is not set");
    going_down(1);
  }

  /*
   * Initialize global options structure.
   */
  init_global_options();

  /*
   * Partially initialize hostd[].  This
   * is completed in get_args().
   */
  if ((domdot = strchr(hostname, '.'))) {
    /*
     * Hostname already contains domainname.
     * Split out hostname and domainname
     * components
     */
    *domdot++ = '\0';
    hostdomain = domdot;
  }
  xstrlcpy(hostd, hostname, sizeof(hostd));
  am_set_hostname(hostname);

  /*
   * Setup signal handlers
   */
  /* SIGINT: trap interrupts for shutdowns */
  setup_sighandler(SIGINT, sigterm);
  /* SIGTERM: trap terminate so we can shutdown cleanly (some chance) */
  setup_sighandler(SIGTERM, sigterm);
  /* SIGHUP: hangups tell us to reload the cache */
  setup_sighandler(SIGHUP, sighup);
  /*
   * SIGCHLD: trap Death-of-a-child.  These allow us to pick up the exit
   * status of backgrounded mounts.  See "sched.c".
   */
  setup_sighandler(SIGCHLD, sigchld);
#ifdef HAVE_SIGACTION
  /* construct global "masked_sigs" used in nfs_start.c */
  sigemptyset(&masked_sigs);
  sigaddset(&masked_sigs, SIGINT);
  sigaddset(&masked_sigs, SIGTERM);
  sigaddset(&masked_sigs, SIGHUP);
  sigaddset(&masked_sigs, SIGCHLD);
#endif /* HAVE_SIGACTION */

  /*
   * Fix-up any umask problems.  Most systems default
   * to 002 which is not too convenient for our purposes
   */
  orig_umask = umask(0);

  /*
   * Figure out primary network name
   */
  getwire(&PrimNetName, &PrimNetNum);

  /*
   * Determine command-line arguments
   */
  get_args(argc, argv);

  /*
   * Log version information.
   */
  vertmp = get_version_string();
  verstr = strtok(vertmp, "\n");
  plog(XLOG_INFO, "AM-UTILS VERSION INFORMATION:");
  while (verstr) {
    plog(XLOG_INFO, "%s", verstr);
    verstr = strtok(NULL, "\n");
  }
  XFREE(vertmp);

  /*
   * Get our own IP address so that we can mount the automounter.  We pass
   * localhost_address which could be used as the default localhost
   * name/address in amu_get_myaddress().
   */
  amu_get_myaddress(&myipaddr, gopt.localhost_address);
  plog(XLOG_INFO, "My ip addr is %s", inet_ntoa(myipaddr));

  /* avoid hanging on other NFS servers if started elsewhere */
  if (chdir("/") < 0)
    plog(XLOG_INFO, "cannot chdir to /: %m");

  /*
   * Now check we are root.
   */
  if (geteuid() != 0) {
    plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %ld)", (long) geteuid());
    going_down(1);
  }

#ifdef HAVE_MAP_NIS
  /*
   * If the domain was specified then bind it here
   * to circumvent any default bindings that may
   * be done in the C library.
   */
  if (gopt.nis_domain && yp_bind(gopt.nis_domain)) {
    plog(XLOG_FATAL, "Can't bind to NIS domain \"%s\"", gopt.nis_domain);
    going_down(1);
  }
#endif /* HAVE_MAP_NIS */

  if (!amuDebug(D_DAEMON))
    ppid = daemon_mode();

  /*
   * Lock process text and data segment in memory.
   */
  if (gopt.flags & CFM_PROCESS_LOCK) {
    do_memory_locking();
  }

  do_mapc_reload = clocktime(NULL) + gopt.map_reload_interval;

  /*
   * Register automounter with system.
   */
  error = mount_automounter(ppid);
  if (error && ppid)
    kill(ppid, SIGALRM);

#ifdef HAVE_FS_AUTOFS
  /*
   * XXX this should be part of going_down(), but I can't move it there
   * because it would be calling non-library code from the library... ugh
   */
  if (amd_use_autofs)
    destroy_autofs_service();
#endif /* HAVE_FS_AUTOFS */

  going_down(error);

  abort();
  return 1; /* should never get here */
}
Exemplo n.º 26
0
int
mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto, const char *mnttabname, int on_autofs)
{
  int error = 0;
#ifdef MOUNT_TABLE_ON_FILE
  char *zopts = NULL, *xopts = NULL;
  size_t l;
#endif /* MOUNT_TABLE_ON_FILE */
  char *mnt_dir = NULL;

#ifdef NEED_AUTOFS_SPACE_HACK
  char *old_mnt_dir = NULL;
  /* perform space hack */
  if (on_autofs) {
    old_mnt_dir = mnt->mnt_dir;
    mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir);
  } else
#endif /* NEED_AUTOFS_SPACE_HACK */
    mnt_dir = strdup(mnt->mnt_dir);

  dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)",
       mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);

again:
  error = MOUNT_TRAP(type, mnt, flags, mnt_data);

  if (error < 0) {
    plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir);
    /*
     * The following code handles conditions which shouldn't
     * occur.  They are possible either because amd screws up
     * in preparing for the mount, or because some human
     * messed with the mount point.  Both have been known to
     * happen. -- stolcke 2/22/95
     */
    if (errno == EBUSY) {
      /*
       * Also, sometimes unmount isn't called, e.g., because
       * our mountlist is garbled.  This leaves old mount
       * points around which need to be removed before we
       * can mount something new in their place.
       */
      errno = umount_fs(mnt_dir, mnttabname, on_autofs);
      if (errno != 0)
	plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir);
      else {
	plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir);
	error = MOUNT_TRAP(type, mnt, flags, mnt_data);
      }
    }
  }

  if (error < 0 && --retry > 0) {
    sleep(1);
    goto again;
  }

#ifdef NEED_AUTOFS_SPACE_HACK
  /* Undo space hack */
  if (on_autofs)
    mnt->mnt_dir = old_mnt_dir;
#endif /* NEED_AUTOFS_SPACE_HACK */

  if (error < 0) {
    error = errno;
    goto out;
  }

#ifdef MOUNT_TABLE_ON_FILE
  /*
   * Allocate memory for options:
   *        dev=..., vers={2,3}, proto={tcp,udp}
   */
  l = strlen(mnt->mnt_opts) + 48;
  zopts = (char *) xmalloc(l);

  /* copy standard options */
  xopts = mnt->mnt_opts;

  xstrlcpy(zopts, xopts, l);

# ifdef MNTTAB_OPT_DEV
  {
    /* add the extra dev= field to the mount table */
    struct stat stb;
    if (lstat(mnt_dir, &stb) == 0) {
      char optsbuf[48];
      if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */
	xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx",
		  MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff);
      else			/* e.g. System Vr4 */
	xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx",
		  MNTTAB_OPT_DEV, (u_long) stb.st_dev);
      append_opts(zopts, l, optsbuf);
    }
  }
# endif /* MNTTAB_OPT_DEV */

# if defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)
  /*
   * add the extra vers={2,3} field to the mount table,
   * unless already specified by user
   */
   if (nfs_version == NFS_VERSION3 &&
       hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) {
     char optsbuf[48];
     xsnprintf(optsbuf, sizeof(optsbuf),
	       "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3);
     append_opts(zopts, l, optsbuf);
   }
# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */

# ifdef MNTTAB_OPT_PROTO
  /*
   * add the extra proto={tcp,udp} field to the mount table,
   * unless already specified by user.
   */
  if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) {
    char optsbuf[48];
    xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto);
    append_opts(zopts, l, optsbuf);
  }
# endif /* MNTTAB_OPT_PROTO */

  /* finally, store the options into the mount table structure */
  mnt->mnt_opts = zopts;

  /*
   * Additional fields in mntent_t
   * are fixed up here
   */
# ifdef HAVE_MNTENT_T_MNT_CNODE
  mnt->mnt_cnode = 0;
# endif /* HAVE_MNTENT_T_MNT_CNODE */

# ifdef HAVE_MNTENT_T_MNT_RO
  mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL);
# endif /* HAVE_MNTENT_T_MNT_RO */

# ifdef HAVE_MNTENT_T_MNT_TIME
#  ifdef HAVE_MNTENT_T_MNT_TIME_STRING
  {				/* allocate enough space for a long */
    size_t l = 13 * sizeof(char);
    char *str = (char *) xmalloc(l);
    xsnprintf(str, l, "%ld", time((time_t *) NULL));
    mnt->mnt_time = str;
  }
#  else /* not HAVE_MNTENT_T_MNT_TIME_STRING */
  mnt->mnt_time = time((time_t *) NULL);
#  endif /* not HAVE_MNTENT_T_MNT_TIME_STRING */
# endif /* HAVE_MNTENT_T_MNT_TIME */

  write_mntent(mnt, mnttabname);

# ifdef MNTTAB_OPT_DEV
  if (xopts) {
    XFREE(mnt->mnt_opts);
    mnt->mnt_opts = xopts;
  }
# endif /* MNTTAB_OPT_DEV */
#endif /* MOUNT_TABLE_ON_FILE */

 out:
  XFREE(mnt_dir);
  return error;
}
Exemplo n.º 27
0
Arquivo: xutil.c Projeto: 0mp/freebsd
void
am_set_hostname(char *hn)
{
  xstrlcpy(am_hostname, hn, sizeof(am_hostname));
}
Exemplo n.º 28
0
/*
 * Write out a mount list
 */
void
rewrite_mtab(mntlist *mp, const char *mnttabname)
{
  FILE *mfp;
  int error = 0;
  char tmpname[64];
  int retries;
  int tmpfd;
  char *cp;
  char mcp[128];

  if (!mtab_is_writable()) {
    return;
  }

  /*
   * Concoct a temporary name in the same directory as the target mount
   * table so that rename() will work.
   */
  xstrlcpy(mcp, mnttabname, sizeof(mcp));
  cp = strrchr(mcp, '/');
  if (cp) {
    memmove(tmpname, mcp, cp - mcp);
    tmpname[cp - mcp] = '\0';
  } else {
    plog(XLOG_WARNING, "No '/' in mtab (%s), using \".\" as tmp directory", mnttabname);
    tmpname[0] = '.';
    tmpname[1] = '\0';
  }
  xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname));
  retries = 0;
 enfile1:
#ifdef HAVE_MKSTEMP
  tmpfd = mkstemp(tmpname);
  fchmod(tmpfd, 0644);
#else /* not HAVE_MKSTEMP */
  mktemp(tmpname);
  tmpfd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC, 0644);
#endif /* not HAVE_MKSTEMP */
  if (tmpfd < 0) {
    if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto enfile1;
    }
    plog(XLOG_ERROR, "%s: open: %m", tmpname);
    return;
  }
  if (close(tmpfd) < 0)
    plog(XLOG_ERROR, "Couldn't close tmp file descriptor: %m");

  retries = 0;
 enfile2:
  mfp = setmntent(tmpname, "w");
  if (!mfp) {
    if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto enfile2;
    }
    plog(XLOG_ERROR, "setmntent(\"%s\", \"w\"): %m", tmpname);
    error = 1;
    goto out;
  }
  while (mp) {
    if (mp->mnt) {
      if (addmntent(mfp, mp->mnt)) {
	plog(XLOG_ERROR, "Can't write entry to %s", tmpname);
	error = 1;
	goto out;
      }
    }
    mp = mp->mnext;
  }

  /*
   * SunOS 4.1 manuals say that the return code from entmntent()
   * is always 1 and to treat as a void.  That means we need to
   * call fflush() to make sure the new mtab file got written.
   */
  if (fflush(mfp)) {
    plog(XLOG_ERROR, "flush new mtab file: %m");
    error = 1;
    goto out;
  }
  (void) endmntent(mfp);

  /*
   * Rename temporary mtab to real mtab
   */
  if (rename(tmpname, mnttabname) < 0) {
    plog(XLOG_ERROR, "rename %s to %s: %m", tmpname, mnttabname);
    error = 1;
    goto out;
  }
 out:
  if (error)
    (void) unlink(tmpname);
}
Exemplo n.º 29
0
nfsdiropres *
nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp)
{
  static nfsdiropres res;
  int idx;
  uid_t uid = (uid_t) INVALIDID;
  gid_t gid = (gid_t) INVALIDID;

  if (!started) {
    started++;
    rootfattr.na_ctime = startup;
    rootfattr.na_mtime = startup;
    slinkfattr.na_ctime = startup;
    slinkfattr.na_mtime = startup;
    un_fattr.na_ctime = startup;
    un_fattr.na_mtime = startup;
  }

  if (eq_fh(&argp->da_fhandle, &slink)) {
    res.dr_status = NFSERR_NOTDIR;
    return &res;
  }

  if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0) {
    res.dr_status = NFSERR_NOENT;
    return &res;
  }
  if (eq_fh(&argp->da_fhandle, &root)) {
    if (argp->da_name[0] == '.' &&
	(argp->da_name[1] == '\0' ||
	 (argp->da_name[1] == '.' &&
	  argp->da_name[2] == '\0'))) {
#if 0
    /*
     * XXX: increment mtime of parent directory, causes NFS clients to
     * invalidate their cache for that directory.
     * Some NFS clients may need this code.
     */
      if (uid != rootfattr.na_uid) {
	clocktime(&rootfattr.na_mtime);
	rootfattr.na_uid = uid;
      }
#endif /* 0 */
      res.dr_u.dr_drok_u.drok_fhandle = root;
      res.dr_u.dr_drok_u.drok_attributes = rootfattr;
      res.dr_status = NFS_OK;
      return &res;
    }

    if (STREQ(argp->da_name, slinkname)) {
#ifndef MNT2_NFS_OPT_SYMTTL
      /*
       * This code is needed to defeat Solaris 2.4's (and newer) symlink
       * values cache.  It forces the last-modified time of the symlink to be
       * current.  It is not needed if the O/S has an nfs flag to turn off the
       * symlink-cache at mount time (such as Irix 5.x and 6.x). -Erez.
       *
       * Additionally, Linux currently ignores the nt_useconds field,
       * so we must update the nt_seconds field every time.
       */
      if (uid != slinkfattr.na_uid) {
	clocktime(&slinkfattr.na_mtime);
	slinkfattr.na_uid = uid;
      }
#endif /* not MNT2_NFS_OPT_SYMTTL */
      res.dr_u.dr_drok_u.drok_fhandle = slink;
      res.dr_u.dr_drok_u.drok_attributes = slinkfattr;
      res.dr_status = NFS_OK;
      return &res;
    }

    if (gid != hlfs_gid) {
      res.dr_status = NFSERR_NOENT;
      return &res;
    }

    /* if gets here, gid == hlfs_gid */
    if ((idx = untab_index(argp->da_name)) < 0) {
      res.dr_status = NFSERR_NOENT;
      return &res;
    } else {			/* entry found and gid is permitted */
      u_int xuid;
      un_fattr.na_fileid = untab[idx].uid;
      res.dr_u.dr_drok_u.drok_attributes = un_fattr;
      memset(&un_fhandle, 0, sizeof(am_nfs_fh));
      xuid = (u_int) untab[idx].uid;
      memcpy(un_fhandle.fh_data, &xuid, sizeof(xuid));
      xstrlcpy((char *) &un_fhandle.fh_data[sizeof(xuid)],
	       untab[idx].username,
	       sizeof(am_nfs_fh) - sizeof(xuid));
      res.dr_u.dr_drok_u.drok_fhandle = un_fhandle;
      res.dr_status = NFS_OK;
      dlog("nfs_lookup: successful lookup for uid=%ld, gid=%ld: username=%s",
	   (long) uid, (long) gid, untab[idx].username);
      return &res;
    }
  } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */

  res.dr_status = NFSERR_STALE;
  return &res;
}
Exemplo n.º 30
0
/*
 * Map from conventional mount arguments
 * to Solaris 2.x (SunOS 5.x) style arguments.
 */
int
mount_svr4(char *fsname, char *dir, int flags, MTYPE_TYPE type, caddr_t data, const char *optstr)
{
#if defined(MNT2_GEN_OPT_OPTIONSTR) && defined(MAX_MNTOPT_STR)
  char mountopts[MAX_MNTOPT_STR];

  /*
   * Save a copy of the mount options.  The kernel will overwrite them with
   * those it recognizes.
   */
  xstrlcpy(mountopts, optstr, MAX_MNTOPT_STR);
#endif /* defined(MNT2_GEN_OPT_OPTIONSTR) && defined(MAX_MNTOPT_STR) */

#if defined(MOUNT_TYPE_NFS3) && defined(MNTTAB_TYPE_NFS3)
  if (STREQ(type, MOUNT_TYPE_NFS3)) {
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(nfs_args_t));
  }
#endif /* defined(MOUNT_TYPE_NFS3) && defined(MNTTAB_TYPE_NFS3) */

#if defined(MOUNT_TYPE_NFS) && defined(MNTTAB_TYPE_NFS)
  if (STREQ(type, MOUNT_TYPE_NFS)) {
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(nfs_args_t));
  }
#endif /* defined(MOUNT_TYPE_NFS) && defined(MNTTAB_TYPE_NFS) */

#if defined(MOUNT_TYPE_AUTOFS) && defined(MNTTAB_TYPE_AUTOFS)
  if (STREQ(type, MOUNT_TYPE_AUTOFS)) {
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(autofs_args_t));
  }
#endif /* defined(MOUNT_TYPE_AUTOFS) && defined(MNTTAB_TYPE_AUTOFS) */

#if defined(MOUNT_TYPE_UFS) && defined(MNTTAB_TYPE_UFS)
  if (STREQ(type, MOUNT_TYPE_UFS))
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(ufs_args_t));
#endif /* defined(MOUNT_TYPE_UFS) && defined(MNTTAB_TYPE_UFS) */

#if defined(MOUNT_TYPE_PCFS) && defined(MNTTAB_TYPE_PCFS)
  if (STREQ(type, MOUNT_TYPE_PCFS))
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(pcfs_args_t));
#endif /* defined(MOUNT_TYPE_PCFS) && defined(MNTTAB_TYPE_PCFS) */

#if defined(MOUNT_TYPE_CDFS) && defined(MNTTAB_TYPE_CDFS)
  /*
   * HSFS on Solaris allows for 3 HSFSMNT_* flags to be passed
   * as arguments to the mount().  These flags are bit fields in an
   * integer, and that integer is passed as the "data" of this system
   * call.  The flags are described in <sys/fs/hsfs_rrip.h>.  However,
   * Solaris does not have an interface to these.  It does not define
   * a structure hsfs_args or anything that one can figure out what
   * arguments to pass to mount(2) for this type of filesystem.
   * Therefore, until Sun does, no arguments are passed to this mount
   * below.
   * -Erez Zadok <*****@*****.**>.
   */
  if (STREQ(type, MOUNT_TYPE_CDFS))
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_FSS | flags),
		     type, (char *) NULL, 0);
#endif /* defined(MOUNT_TYPE_CDFS) && defined(MNTTAB_TYPE_CDFS) */

#if defined(MOUNT_TYPE_LOFS) && defined(MNTTAB_TYPE_LOFS)
  if (STREQ(type, MOUNT_TYPE_LOFS))
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_FSS | flags),
		     type, (char *) NULL, 0);
#endif /* defined(MOUNT_TYPE_LOFS) && defined(MNTTAB_TYPE_LOFS) */

#ifdef HAVE_FS_CACHEFS
# if defined(MOUNT_TYPE_CACHEFS) && defined(MNTTAB_TYPE_CACHEFS)
  if (STREQ(type, MOUNT_TYPE_CACHEFS))
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(cachefs_args_t));
# endif /* defined(MOUNT_TYPE_CACHEFS) && defined(MNTTAB_TYPE_CACHEFS) */
#endif /*HAVE_FS_CACHEFS */

#ifdef HAVE_FS_AUTOFS
# if defined(MOUNT_TYPE_AUTOFS) && defined(MNTTAB_TYPE_AUTOFS)
  if (STREQ(type, MOUNT_TYPE_AUTOFS))
    return sys_mount(fsname, dir, (MNT2_GEN_OPT_DATA | flags),
		     type, (char *) data, sizeof(autofs_args_t));
# endif /* defined(MOUNT_TYPE_AUTOFS) && defined(MNTTAB_TYPE_AUTOFS) */
#endif /* HAVE_FS_AUTOFS */

  return EINVAL;
}