610 |
} |
} |
611 |
|
|
612 |
|
|
|
/* callback-helper of netfs_attempt_lookup, check whether the name of |
|
|
* file (of this callback) is equal to the one we're looking for, in case |
|
|
* set 'found' from fuse_dirh_t handle to TRUE. |
|
|
* |
|
|
* version for new fuse API (since 2.1) |
|
|
*/ |
|
|
static int |
|
|
fuse_lookup_helper(fuse_dirh_t handle, const char *name, int type, ino_t ino) |
|
|
{ |
|
|
(void) type; /* we want to know whether the file exists at all, |
|
|
* the type is not of any interest */ |
|
|
(void) ino; /* we don't care for inodes here, netfs_validate_stat does it */ |
|
|
|
|
|
if(! strcmp(name, handle->filename)) |
|
|
{ |
|
|
handle->found = 1; |
|
|
return ENOMEM; /* send ENOMEM to stop being called, TODO make sure that |
|
|
* all programs, depending on libfuse, can live with that. |
|
|
*/ |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |
|
|
|
|
|
|
|
|
/* callback-helper of netfs_attempt_lookup, check whether the name of |
|
|
* file (of this callback) is equal to the one we're looking for, in case |
|
|
* set 'found' from fuse_dirh_t handle to TRUE. |
|
|
* |
|
|
* version for old API |
|
|
*/ |
|
|
static int |
|
|
fuse_lookup_helper_compat(fuse_dirh_t handle, const char *name, int type) |
|
|
{ |
|
|
assert(fuse_use_ino == 0); |
|
|
return fuse_lookup_helper(handle, name, type, 0); /* set ino to 0, it will |
|
|
* be ignored anyways, |
|
|
* since fuse_use_ino |
|
|
* is off. */ |
|
|
} |
|
|
|
|
613 |
/* Lookup NAME in DIR for USER; set *NODE to the found name upon return. If |
/* Lookup NAME in DIR for USER; set *NODE to the found name upon return. If |
614 |
the name was not found, then return ENOENT. On any error, clear *NODE. |
the name was not found, then return ENOENT. On any error, clear *NODE. |
615 |
(*NODE, if found, should be locked, this call should unlock DIR no matter |
(*NODE, if found, should be locked, this call should unlock DIR no matter |
621 |
name, dir->nn->path); |
name, dir->nn->path); |
622 |
|
|
623 |
error_t err; |
error_t err; |
|
fuse_dirh_t handle = NULL; |
|
624 |
|
|
625 |
if((err = netfs_validate_stat(dir, user)) |
if((err = netfs_validate_stat(dir, user)) |
626 |
|| (err = fshelp_access(&dir->nn_stat, S_IREAD, user)) |
|| (err = fshelp_access(&dir->nn_stat, S_IREAD, user)) |
650 |
err = EAGAIN; |
err = EAGAIN; |
651 |
} |
} |
652 |
|
|
653 |
else if(FUSE_OP_HAVE(getdir)) |
else if(FUSE_OP_HAVE(getattr)) |
654 |
{ |
{ |
655 |
/* lookup for common file */ |
/* lookup for common file */ |
656 |
struct netnode *nn; |
struct netnode *nn; |
657 |
char *path; |
char *path; |
658 |
|
struct stat stbuf; |
659 |
|
|
660 |
if(! (handle = malloc(sizeof(struct fuse_dirhandle)))) |
if(asprintf(&path, "%s/%s", |
661 |
{ |
dir->nn->parent ? dir->nn->path : "", name) < 0) |
|
err = ENOMEM; /* sorry, translator not available ... */ |
|
|
goto out; |
|
|
} |
|
|
|
|
|
handle->found = 0; |
|
|
handle->filename = name; |
|
|
|
|
|
if(fuse_ops) |
|
|
fuse_ops->getdir(dir->nn->path, handle, fuse_lookup_helper); |
|
|
else |
|
|
fuse_ops_compat->getdir(dir->nn->path, handle, |
|
|
fuse_lookup_helper_compat); |
|
|
|
|
|
/* we cannot rely on exit status of ->getdir() func, since we |
|
|
* return an error from the helper to abort write out |
|
|
*/ |
|
|
|
|
|
if(! handle->found) |
|
|
{ |
|
|
err = ENOENT; |
|
|
goto out; |
|
|
} |
|
|
|
|
|
/* well, file exists - create a handle ... */ |
|
|
if(! (path = malloc(strlen(dir->nn->path) + strlen(name) + 2))) |
|
662 |
{ |
{ |
663 |
err = ENOMEM; |
err = ENOMEM; |
664 |
goto out; |
goto out; |
665 |
} |
} |
666 |
|
|
667 |
sprintf(path, "%s/%s", dir->nn->parent ? dir->nn->path : "", name); |
if(! (err = -FUSE_OP_CALL(getattr, path, &stbuf))) |
668 |
nn = fuse_make_netnode(dir->nn, path); |
if(! (nn = fuse_make_netnode(dir->nn, path)) || |
669 |
free(path); /* fuse_make_netnode strdup()s the pathname */ |
! (*node = fuse_make_node(nn))) |
|
|
|
|
if(! path) |
|
|
{ |
|
670 |
err = ENOMEM; |
err = ENOMEM; |
|
goto out; |
|
|
} |
|
671 |
|
|
672 |
if((*node = fuse_make_node(nn))) |
free(path); /* fuse_make_netnode strdup()s the pathname */ |
|
err = 0; |
|
673 |
} |
} |
674 |
|
|
675 |
out: |
out: |
680 |
else |
else |
681 |
mutex_lock(&(*node)->lock); |
mutex_lock(&(*node)->lock); |
682 |
|
|
|
free(handle); |
|
683 |
FUNC_EPILOGUE(err); |
FUNC_EPILOGUE(err); |
684 |
} |
} |
685 |
|
|