static int null_int;
static void *null_result = (void *)&null_int;
+/* Check that a string is a valid file name. We require that it be valid
+ * UTF-8, that it not be empty, and that it not contain embedded forward
+ * slashes. Also checks that the length of the string is not more than the
+ * maximum allowed length. This function does allow the names "." and "..".
+ * Returns TRUE if te string is allowed as a filename. */
+gboolean validate_filename(const char *filename)
+{
+ if (filename == NULL || filename[0] == '\0')
+ return FALSE;
+ if (strlen(filename) > 255)
+ return FALSE;
+ if (!g_utf8_validate(filename, -1, NULL))
+ return FALSE;
+ if (strchr(filename, '/') != NULL)
+ return FALSE;
+ return TRUE;
+}
+
/* Look up a BlueSkyInode given an NFS filehandle. Returns NULL if the
* filehandle is invalid. */
BlueSkyInode *lookup_fh(nfs_fh3 *fh)
{
static lookup3res result;
- result.status = NFS3ERR_NOTSUPP;
+ BlueSkyInode *dir = lookup_fh(&argp->dir);
+ if (dir == NULL) {
+ result.status = NFS3ERR_STALE;
+ result.lookup3res_u.resfail.present = FALSE;
+ return &result;
+ }
+
+ result.lookup3res_u.resfail.present = TRUE;
+ encode_fattr3(&result.lookup3res_u.resfail.post_op_attr_u.attributes, dir);
+ if (!validate_filename(argp->name)) {
+ if (strlen(argp->name) > 255)
+ result.status = NFS3ERR_NAMETOOLONG;
+ else
+ result.status = NFS3ERR_NOENT;
+ return &result;
+ }
+
+ /* TODO: Special-case "." and "..". */
+ uint64_t inum = bluesky_directory_lookup(dir, argp->name);
+ if (inum == 0) {
+ result.status = NFS3ERR_NOENT;
+ return &result;
+ }
+ BlueSkyInode *inode = bluesky_get_inode(fs, inum);
+ if (inode == NULL) {
+ result.status = NFS3ERR_NOENT;
+ return &result;
+ }
+
+ result.lookup3res_u.resok.dir_attributes.present = TRUE;
+ encode_fattr3(&result.lookup3res_u.resok.dir_attributes.post_op_attr_u.attributes, dir);
+ result.lookup3res_u.resok.obj_attributes.present = TRUE;
+ encode_fattr3(&result.lookup3res_u.resok.obj_attributes.post_op_attr_u.attributes, inode);
+
+ static uint64_t fh_bytes;
+ fh_bytes = GUINT64_TO_BE(inum);
+ result.lookup3res_u.resok.object.data.data_len = 8;
+ result.lookup3res_u.resok.object.data.data_val = (char *)&fh_bytes;
return &result;
}