static int *xdr_decode_entry(int *p, struct nfs_entry *entry) { entry->fileid = ntohl(*p++); if (!(p = xdr_decode_string(p, entry->name, NFS_MAXNAMLEN))) return NULL; entry->cookie = ntohl(*p++); entry->eof = 0; return p; }
static inline u32 * decode_pathname(u32 *p, char **namp, int *lenp) { char *name; int i; if ((p = xdr_decode_string(p, namp, lenp, NFS3_MAXPATHLEN)) != NULL) { for (i = 0, name = *namp; i < *lenp; i++, name++) { if (*name == '\0') return NULL; } } return p; }
/* * Decode a file name and make sure that the path contains * no slashes or null bytes. */ static inline u32 * decode_filename(u32 *p, char **namp, int *lenp) { char *name; int i; if ((p = xdr_decode_string(p, namp, lenp, NFS_MAXNAMLEN)) != NULL) { for (i = 0, name = *namp; i < *lenp; i++, name++) { if (*name == '\0' || *name == '/') return NULL; } *name = '\0'; } return p; }
int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle, char *res) { int *p, *p0; int status; int ruid = 0; PRINTK("NFS call readlink\n"); if (!(p0 = nfs_rpc_alloc())) return -EIO; retry: p = nfs_rpc_header(p0, NFSPROC_READLINK, ruid); p = xdr_encode_fhandle(p, fhandle); if ((status = nfs_rpc_call(server, p0, p)) < 0) { nfs_rpc_free(p0); return status; } if (!(p = nfs_rpc_verify(p0))) status = NFSERR_IO; else if ((status = ntohl(*p++)) == NFS_OK) { if (!(p = xdr_decode_string(p, res, NFS_MAXPATHLEN))) { printk("nfs_proc_readlink: giant pathname\n"); status = NFSERR_IO; } else PRINTK("NFS reply readlink %s\n", res); } else { if (!ruid && current->euid == 0 && current->uid != 0) { ruid = 1; goto retry; } PRINTK("NFS reply readlink failed = %d\n", status); } nfs_rpc_free(p0); return -nfs_stat_to_errno(status); }