Ejemplo n.º 1
0
int 
mnt_proc_mnt(struct generic_server *server, char *directory, 
	     struct nfs_fh *fhandle) {
  
  int *p, *p0;
  int status;

  DPRINTF(CLUHELP2_LEVEL,("MNT call MNT\n"));
  if (!(p0 = overhead_rpc_alloc(server->rsize)))
    return -EIO;

  p = mnt_rpc_header(p0,MNTPROC_MNT,0);
  p = xdr_encode_string(p,directory);
  if ((status = generic_rpc_call(server, p0, p)) < 0) {
    overhead_rpc_free(p0);
    return status;
  }
  if (!(p = generic_rpc_verify(p0)))
    {status = -1;}
  else {
    status = ntohl(*p++);
	if (status == 0)
	  {
	    xdr_decode_fhandle(p, fhandle);
	    fhandle->server = server;
	    DPRINTF(CLUHELP2_LEVEL,("MNTPROC_MNT call good\n"));
	  }
      }
  DPRINTF(CLUHELP2_LEVEL,("pmap proc getmap status: %d\n",status));
  overhead_rpc_free(p0);
  return(status);
}
Ejemplo n.º 2
0
/*
 * Decode diropres reply
 * LOOKUP, CREATE, MKDIR
 */
static int
nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
{
	int	status;

	if ((status = ntohl(*p++)))
		return -nfs_stat_to_errno(status);
	p = xdr_decode_fhandle(p, res->fh);
	xdr_decode_fattr(p, res->fattr);
	return 0;
}
Ejemplo n.º 3
0
int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, const char *name,
		    struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  lookup %s\n", name);
#ifdef NFS_PROC_DEBUG
	if (!strcmp(name, "xyzzy"))
		proc_debug = 1 - proc_debug;
#endif
	if (!(p0 = nfs_rpc_alloc(server->rsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_LOOKUP, ruid);
	p = xdr_encode_fhandle(p, dir);
	p = xdr_encode_string(p, name);
	if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		p = xdr_decode_fhandle(p, fhandle);
		p = xdr_decode_fattr(p, fattr);
		PRINTK("NFS reply lookup\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply lookup failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 4
0
int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
		   const char *name, struct nfs_sattr *sattr,
		   struct nfs_fh *fhandle, struct nfs_fattr *fattr)
{
	int *p, *p0;
	int status;
	int ruid = 0;

	PRINTK("NFS call  mkdir %s\n", name);
	if (!(p0 = nfs_rpc_alloc(server->wsize)))
		return -EIO;
retry:
	p = nfs_rpc_header(p0, NFSPROC_MKDIR, ruid);
	p = xdr_encode_fhandle(p, dir);
	p = xdr_encode_string(p, name);
	p = xdr_encode_sattr(p, sattr);
	if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
		nfs_rpc_free(p0);
		return status;
	}
	if (!(p = nfs_rpc_verify(p0)))
		status = -errno_NFSERR_IO;
	else if ((status = ntohl(*p++)) == NFS_OK) {
		p = xdr_decode_fhandle(p, fhandle);
		p = xdr_decode_fattr(p, fattr);
		PRINTK("NFS reply mkdir\n");
		/* status = 0; */
	}
	else {
		if (!ruid && current->fsuid == 0 && current->uid != 0) {
			ruid = 1;
			goto retry;
		}
		PRINTK("NFS reply mkdir failed = %d\n", status);
		status = -nfs_stat_to_errno(status);
	}
	nfs_rpc_free(p0);
	return status;
}
Ejemplo n.º 5
0
/* Using the mount protocol, lookup NAME at host HOST.
   Return a node for it or null for an error.  If an
   error occurs, a message is automatically sent to stderr. */
struct node *
mount_root (char *name, char *host)
{
  struct sockaddr_in addr;
  struct hostent *h;
  int *p;
  void *rpcbuf;
  int port;
  error_t err;
  struct node *np;
  short pmapport;

  /* Lookup the portmapper port number */
  if (pmap_service_name)
    {
      struct servent *s;

      /* XXX This will always fail! pmap_service_name will always be "sunrpc"
         What should pmap_service_name really be?  By definition the second
	 argument is either "tcp" or "udp"  Thus, is this backwards
	 (as service_name suggests)?  If so, should it read:
             s = getservbyname (pmap_service_name, "udp");
         or is there something I am missing here?  */
      s = getservbyname ("sunrpc", pmap_service_name);
      if (s)
	pmapport = s->s_port;
      else
	pmapport = htons (pmap_service_number);
    }
  else
    pmapport = htons (pmap_service_number);

  /* Lookup the host */
  h = gethostbyname (host);
  if (!h)
    {
      herror (host);
      return 0;
    }

  addr.sin_family = h->h_addrtype;
  memcpy (&addr.sin_addr, h->h_addr_list[0], h->h_length);
  addr.sin_port = pmapport;

  if (mount_port_override)
    addr.sin_port = htons (mount_port);
  else
    {
      /* Formulate and send a PMAPPROC_GETPORT request
	 to lookup the mount program on the server.  */
      if (connect (main_udp_socket, (struct sockaddr *)&addr,
	           sizeof (struct sockaddr_in)) == -1)
	{
	  error (0, errno, "server mount program");
	  return 0;
	}

      p = pmap_initialize_rpc (PMAPPROC_GETPORT, &rpcbuf);
      if (! p)
	{
	  error (0, errno, "creating rpc packet");
	  return 0;
	}

      *(p++) = htonl (MOUNTPROG);
      *(p++) = htonl (MOUNTVERS);
      *(p++) = htonl (IPPROTO_UDP);
      *(p++) = htonl (0);
      err = conduct_rpc (&rpcbuf, &p);
      if (!err)
	{
	  port = ntohl (*p);
	  p++;
	  addr.sin_port = htons (port);
	}
      else if (mount_port)
	addr.sin_port = htons (mount_port);
      else
	{
	  error (0, err, "portmap of mount");
	  goto error_with_rpcbuf;
	}
      free (rpcbuf);
    }

  /* Now, talking to the mount program, fetch a file handle
     for the root. */
  if (connect (main_udp_socket, (struct sockaddr *) &addr,
	       sizeof (struct sockaddr_in)) == -1)
    {
      error (0, errno, "connect");
      goto error_with_rpcbuf;
    }

  p = mount_initialize_rpc (MOUNTPROC_MNT, &rpcbuf);
  if (! p)
    {
      error (0, errno, "rpc");
      goto error_with_rpcbuf;
    }

  p = xdr_encode_string (p, name);
  err = conduct_rpc (&rpcbuf, &p);
  if (err)
    {
      error (0, err, "%s", name);
      goto error_with_rpcbuf;
    }
  /* XXX Protocol spec says this should be a "unix error code"; we'll
     pretend that an NFS error code is what's meant; the numbers match
     anyhow.  */
  err = nfs_error_trans (htonl (*p));
  p++;
  if (err)
    {
      error (0, err, "%s", name);
      goto error_with_rpcbuf;
    }

  /* Create the node for root */
  xdr_decode_fhandle (p, &np);
  free (rpcbuf);
  pthread_mutex_unlock (&np->lock);

  if (nfs_port_override)
    port = nfs_port;
  else
    {
      /* Send another PMAPPROC_GETPORT request to lookup the nfs server. */
      addr.sin_port = pmapport;
      if (connect (main_udp_socket, (struct sockaddr *) &addr,
	           sizeof (struct sockaddr_in)) == -1)
	{
	  error (0, errno, "connect");
	  return 0;
	}

      p = pmap_initialize_rpc (PMAPPROC_GETPORT, &rpcbuf);
      if (! p)
	{
	  error (0, errno, "rpc");
	  goto error_with_rpcbuf;
	}
      *(p++) = htonl (NFS_PROGRAM);
      *(p++) = htonl (NFS_VERSION);
      *(p++) = htonl (IPPROTO_UDP);
      *(p++) = htonl (0);
      err = conduct_rpc (&rpcbuf, &p);
      if (!err)
	{
	  port = ntohl (*p);
	  p++;
	}
      else if (nfs_port)
	port = nfs_port;
      else
	{
	  error (0, err, "portmap of nfs server");
	  goto error_with_rpcbuf;
	}
      free (rpcbuf);
    }

  addr.sin_port = htons (port);
  if (connect (main_udp_socket, (struct sockaddr *) &addr,
	       sizeof (struct sockaddr_in)) == -1)
    {
      error (0, errno, "connect");
      return 0;
    }

  mounted_hostname = host;
  mounted_nfs_port = port;

  return np;

error_with_rpcbuf:
  free (rpcbuf);

  return 0;
}