Example #1
0
static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
                         void *dstbuf, filldir_t filldir)
{
    while (nbytes >= FUSE_NAME_OFFSET) {
        struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
        size_t reclen = FUSE_DIRENT_SIZE(dirent);
        int over;
        if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
            return -EIO;
        if (reclen > nbytes)
            break;
        if (memchr(dirent->name, '/', dirent->namelen) != NULL)
            return -EIO;

        over = filldir(dstbuf, dirent->name, dirent->namelen,
                       file->f_pos, dirent->ino, dirent->type);
        if (over)
            break;

        buf += reclen;
        nbytes -= reclen;
        file->f_pos = dirent->off;
    }

    return 0;
}
Example #2
0
static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
			 struct dir_context *ctx)
{
	while (nbytes >= FUSE_NAME_OFFSET) {
		struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
		size_t reclen = FUSE_DIRENT_SIZE(dirent);
		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
			return -EIO;
		if (reclen > nbytes)
			break;

		if (!dir_emit(ctx, dirent->name, dirent->namelen,
			       dirent->ino, dirent->type))
			break;

		buf += reclen;
		nbytes -= reclen;
		ctx->pos = dirent->off;
	}

	return 0;
}
Example #3
0
int
fuse_internal_readdir_processdata(struct uio *uio,
    size_t reqsize,
    void *buf,
    size_t bufsize,
    void *param)
{
	int err = 0;
	int cou = 0;
	int bytesavail;
	size_t freclen;

	struct dirent *de;
	struct fuse_dirent *fudge;
	struct fuse_iov *cookediov = param;

	if (bufsize < FUSE_NAME_OFFSET) {
		return -1;
	}
	for (;;) {

		if (bufsize < FUSE_NAME_OFFSET) {
			err = -1;
			break;
		}
		fudge = (struct fuse_dirent *)buf;
		freclen = FUSE_DIRENT_SIZE(fudge);

		cou++;

		if (bufsize < freclen) {
			err = ((cou == 1) ? -1 : 0);
			break;
		}
#ifdef ZERO_PAD_INCOMPLETE_BUFS
		if (isbzero(buf, FUSE_NAME_OFFSET)) {
			err = -1;
			break;
		}
#endif

		if (!fudge->namelen || fudge->namelen > MAXNAMLEN) {
			err = EINVAL;
			break;
		}
		bytesavail = GENERIC_DIRSIZ((struct pseudo_dirent *)
					    &fudge->namelen);

		if (bytesavail > uio_resid(uio)) {
			err = -1;
			break;
		}
		fiov_refresh(cookediov);
		fiov_adjust(cookediov, bytesavail);

		de = (struct dirent *)cookediov->base;
		de->d_fileno = fudge->ino;	/* XXX: truncation */
		de->d_reclen = bytesavail;
		de->d_type = fudge->type;
		de->d_namlen = fudge->namelen;
		memcpy((char *)cookediov->base + sizeof(struct dirent) - 
		       MAXNAMLEN - 1,
		       (char *)buf + FUSE_NAME_OFFSET, fudge->namelen);
		((char *)cookediov->base)[bytesavail] = '\0';

		err = uiomove(cookediov->base, cookediov->len, uio);
		if (err) {
			break;
		}
		buf = (char *)buf + freclen;
		bufsize -= freclen;
		uio_setoffset(uio, fudge->off);
	}

	return err;
}
Example #4
0
__private_extern__
int
fuse_internal_readdir_processdata(vnode_t          vp,
                                  uio_t            uio,
                         __unused size_t           reqsize,
                                  void            *buf,
                                  size_t           bufsize,
                                  struct fuse_iov *cookediov,
                                  int             *numdirent)
{
    int err = 0;
    int cou = 0;
    int n   = 0;
    size_t bytesavail;
    size_t freclen;

    struct dirent      *de;
    struct fuse_dirent *fudge;

    if (bufsize < FUSE_NAME_OFFSET) {
        return -1;
    }

    for (;;) {

        if (bufsize < FUSE_NAME_OFFSET) {
            err = -1;
            break;
        }

        fudge = (struct fuse_dirent *)buf;
        freclen = FUSE_DIRENT_SIZE(fudge);

        cou++;

        if (bufsize < freclen) {
            err = ((cou == 1) ? -1 : 0);
            break;
        }

        /*
         * if (isbzero(buf, FUSE_NAME_OFFSET)) {
         *     // zero-pad incomplete buffer
         *     ...
         *     err = -1;
         *     break;
         * }
         */

        if (!fudge->namelen) { 
            err = EINVAL;
            break;
        }

        if (fudge->namelen > FUSE_MAXNAMLEN) {
            err = EIO;
            break;
        }

#define GENERIC_DIRSIZ(dp) \
  ((sizeof(struct dirent) - (FUSE_MAXNAMLEN + 1)) + \
   (((dp)->d_namlen + 1 + 3) & ~3))

        bytesavail = GENERIC_DIRSIZ((struct pseudo_dirent *)&fudge->namelen); 

        if (bytesavail > (size_t)uio_resid(uio)) {
            err = -1;
            break;
        }

        fiov_refresh(cookediov);
        fiov_adjust(cookediov, bytesavail);

        de = (struct dirent *)cookediov->base;
#if __DARWIN_64_BIT_INO_T
        de->d_fileno = fudge->ino;
#else
        de->d_fileno = (ino_t)fudge->ino; /* XXX: truncation */
#endif /* __DARWIN_64_BIT_INO_T */
        de->d_reclen = bytesavail;
        de->d_type   = fudge->type; 
        de->d_namlen = fudge->namelen;

        /* Filter out any ._* files if the mount is configured as such. */
        if (fuse_skip_apple_double_mp(vnode_mount(vp),
                                      fudge->name, fudge->namelen)) {
            de->d_fileno = 0;
            de->d_type = DT_WHT;
        }

        memcpy((char *)cookediov->base +
               sizeof(struct dirent) - FUSE_MAXNAMLEN - 1,
               (char *)buf + FUSE_NAME_OFFSET, fudge->namelen);
        ((char *)cookediov->base)[bytesavail] = '\0';

        err = uiomove(cookediov->base, (int)cookediov->len, uio);
        if (err) {
            break;
        }

        n++;

        buf = (char *)buf + freclen;
        bufsize -= freclen;
        uio_setoffset(uio, fudge->off);
    }

    if (!err && numdirent) {
        *numdirent = n;
    }

    return err;
}