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); }
/* * 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; }
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; }
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; }
/* 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; }