/************************************************************************** NFS_LOOKUP - Lookup Pathname **************************************************************************/ static void nfs_lookup_req(char *fname) { uint32_t data[1024]; uint32_t *p; int len; int fnamelen; fnamelen = strlen(fname); p = &(data[0]); p = (uint32_t *)rpc_add_credentials((long *)p); memcpy(p, dirfh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = htonl(fnamelen); if (fnamelen & 3) *(p + fnamelen / 4) = 0; memcpy(p, fname, fnamelen); p += (fnamelen + 3) / 4; len = (uint32_t *)p - (uint32_t *)&(data[0]); rpc_req(PROG_NFS, NFS_LOOKUP, data, len); }
static void *nfs_readdirattr_req(struct file_priv *priv, int *plen, uint32_t cookie) { uint32_t data[1024]; uint32_t *p; int len; int ret; void *buf; p = &(data[0]); p = rpc_add_credentials(p); memcpy(p, priv->filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = htonl(cookie); /* cookie */ *p++ = htonl(1024); /* count */ *p++ = 0; len = p - &(data[0]); ret = rpc_req(priv->npriv, PROG_NFS, NFS_READDIR, data, len); if (ret) return NULL; *plen = nfs_len - sizeof(struct rpc_reply) + 4; buf = xzalloc(*plen); memcpy(buf, nfs_packet + sizeof(struct rpc_reply) + 4, *plen); return buf; }
/* * nfs_read_req - Read File on NFS Server */ static int nfs_read_req(struct file_priv *priv, int offset, int readlen) { uint32_t data[1024]; uint32_t *p; uint32_t *filedata; int len; int ret; int rlen; p = &(data[0]); p = rpc_add_credentials(p); memcpy (p, priv->filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = htonl(offset); *p++ = htonl(readlen); *p++ = 0; len = p - &(data[0]); ret = rpc_req(priv->npriv, PROG_NFS, NFS_READ, data, len); if (ret) return ret; filedata = (uint32_t *)(nfs_packet + sizeof(struct rpc_reply)); rlen = ntohl(net_read_uint32(filedata + 18)); kfifo_put(priv->fifo, (char *)(filedata + 19), rlen); return 0; }
static int nfs_attr_req(struct file_priv *priv, struct stat *s) { uint32_t data[1024]; uint32_t *p; int len; int ret; struct fattr *fattr; uint32_t type; p = &(data[0]); p = rpc_add_credentials(p); memcpy(p, priv->filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = 0; len = p - &(data[0]); ret = rpc_req(priv->npriv, PROG_NFS, NFS_GETATTR, data, len); if (ret) return ret; fattr = nfs_packet + sizeof(struct rpc_reply) + 4; type = ntohl(net_read_uint32(&fattr->type)); s->st_size = ntohl(net_read_uint32(&fattr->size)); s->st_mode = ntohl(net_read_uint32(&fattr->mode)); return 0; }
/* * nfs_lookup_req - Lookup Pathname */ static int nfs_lookup_req(struct file_priv *priv, const char *filename, int fnamelen) { uint32_t data[1024]; uint32_t *p; int len; int ret; p = &(data[0]); p = rpc_add_credentials(p); memcpy(p, priv->filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = htonl(fnamelen); if (fnamelen & 3) *(p + fnamelen / 4) = 0; memcpy(p, filename, fnamelen); p += (fnamelen + 3) / 4; len = p - &(data[0]); ret = rpc_req(priv->npriv, PROG_NFS, NFS_LOOKUP, data, len); if (ret) return ret; memcpy(priv->filefh, nfs_packet + sizeof(struct rpc_reply) + 4, NFS_FHSIZE); return 0; }
/* * nfs_mount_req - Mount an NFS Filesystem */ static int nfs_mount_req(struct nfs_priv *npriv) { uint32_t data[1024]; uint32_t *p; int len; int pathlen; int ret; pathlen = strlen(npriv->path); debug("%s: %s\n", __func__, npriv->path); p = &(data[0]); p = rpc_add_credentials(p); *p++ = htonl(pathlen); if (pathlen & 3) *(p + pathlen / 4) = 0; memcpy (p, npriv->path, pathlen); p += (pathlen + 3) / 4; len = p - &(data[0]); ret = rpc_req(npriv, PROG_MOUNT, MOUNT_ADDENTRY, data, len); if (ret) return ret; memcpy(npriv->rootfh, nfs_packet + sizeof(struct rpc_reply) + 4, NFS_FHSIZE); return 0; }
/* * rpc_lookup_req - Lookup RPC Port numbers */ static int rpc_lookup_req(struct nfs_priv *npriv, int prog, int ver) { uint32_t data[16]; int ret; uint32_t port; data[0] = 0; data[1] = 0; /* auth credential */ data[2] = 0; data[3] = 0; /* auth verifier */ data[4] = htonl(prog); data[5] = htonl(ver); data[6] = htonl(17); /* IP_UDP */ data[7] = 0; ret = rpc_req(npriv, PROG_PORTMAP, PORTMAP_GETPORT, data, 8); if (ret) return ret; port = net_read_uint32((uint32_t *)(nfs_packet + sizeof(struct rpc_reply))); switch (prog) { case PROG_MOUNT: npriv->mount_port = ntohl(port); debug("mount port: %d\n", npriv->mount_port); break; case PROG_NFS: npriv->nfs_port = ntohl(port); debug("nfs port: %d\n", npriv->nfs_port); break; default: return -EINVAL; } return 0; }
/************************************************************************** RPC_LOOKUP - Lookup RPC Port numbers **************************************************************************/ static void rpc_lookup_req(int prog, int ver) { uint32_t data[16]; data[0] = 0; data[1] = 0; /* auth credential */ data[2] = 0; data[3] = 0; /* auth verifier */ data[4] = htonl(prog); data[5] = htonl(ver); data[6] = htonl(17); /* IP_UDP */ data[7] = 0; rpc_req(PROG_PORTMAP, PORTMAP_GETPORT, data, 8); }
/*************************************************************************** * NFS_READLINK (AH 2003-07-14) * This procedure is called when read of the first block fails - * this probably happens when it's a directory or a symlink * In case of successful readlink(), the dirname is manipulated, * so that inside the nfs() function a recursion can be done. **************************************************************************/ static void nfs_readlink_req(void) { uint32_t data[1024]; uint32_t *p; int len; p = &(data[0]); p = rpc_add_credentials(p); memcpy (p, filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); len = p - &(data[0]); rpc_req(PROG_NFS, NFS_READLINK, data, len); }
/************************************************************************** NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server **************************************************************************/ static void nfs_umountall_req(void) { uint32_t data[1024]; uint32_t *p; int len; if (nfs_server_mount_port < 0) /* Nothing mounted, nothing to umount */ return; p = &(data[0]); p = rpc_add_credentials(p); len = p - &(data[0]); rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len); }
/************************************************************************** NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server **************************************************************************/ static void nfs_umountall_req(void) { uint32_t data[1024]; uint32_t *p; int len; if ((NfsSrvMountPort == -1) || (!fs_mounted)) /* Nothing mounted, nothing to umount */ return; p = &(data[0]); p = (uint32_t *)rpc_add_credentials((long *)p); len = (uint32_t *)p - (uint32_t *)&(data[0]); rpc_req(PROG_MOUNT, MOUNT_UMOUNTALL, data, len); }
/************************************************************************** NFS_READ - Read File on NFS Server **************************************************************************/ static void nfs_read_req(int offset, int readlen) { uint32_t data[1024]; uint32_t *p; int len; p = &(data[0]); p = rpc_add_credentials(p); memcpy (p, filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); *p++ = htonl(offset); *p++ = htonl(readlen); *p++ = 0; len = p - &(data[0]); rpc_req(PROG_NFS, NFS_READ, data, len); }
/************************************************************************** NFS_MOUNT - Mount an NFS Filesystem **************************************************************************/ static void nfs_mount_req (char *path) { uint32_t data[1024]; uint32_t *p; int len; int pathlen; pathlen = strlen (path); p = &(data[0]); p = (uint32_t *)rpc_add_credentials((long *)p); *p++ = htonl(pathlen); if (pathlen & 3) *(p + pathlen / 4) = 0; memcpy (p, path, pathlen); p += (pathlen + 3) / 4; len = (uint32_t *)p - (uint32_t *)&(data[0]); rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len); }
/* * nfs_umountall_req - Unmount all our NFS Filesystems on the Server */ static void nfs_umount_req(struct nfs_priv *npriv) { uint32_t data[1024]; uint32_t *p; int len; int pathlen; pathlen = strlen(npriv->path); p = &(data[0]); p = rpc_add_credentials(p); *p++ = htonl(pathlen); if (pathlen & 3) *(p + pathlen / 4) = 0; memcpy (p, npriv->path, pathlen); p += (pathlen + 3) / 4; len = p - &(data[0]); rpc_req(npriv, PROG_MOUNT, MOUNT_UMOUNT, data, len); }
static int nfs_readlink_req(struct file_priv *priv, char* buf, size_t size) { uint32_t data[1024]; uint32_t *p; int len; int ret; char *path; uint32_t *filedata; p = &(data[0]); p = rpc_add_credentials(p); memcpy(p, priv->filefh, NFS_FHSIZE); p += (NFS_FHSIZE / 4); len = p - &(data[0]); ret = rpc_req(priv->npriv, PROG_NFS, NFS_READLINK, data, len); if (ret) return ret; filedata = nfs_packet + sizeof(struct rpc_reply); filedata++; len = ntohl(net_read_uint32(filedata)); /* new path length */ filedata++; path = (char *)filedata; if (len > size) len = size; memcpy(buf, path, len); return 0; }