Example #1
0
int
dtfs_node_readdir(struct puffs_usermount *pu, void *opc,
	struct dirent *dent, off_t *readoff, size_t *reslen,
	const struct puffs_cred *pcr,
	int *eofflag, off_t *cookies, size_t *ncookies)
{
	struct puffs_node *pn = opc;
	struct puffs_node *pn_nth;
	struct dtfs_dirent *dfd_nth;

	if (pn->pn_va.va_type != VDIR)
		return ENOTDIR;
	
	dtfs_updatetimes(pn, 1, 0, 0);

	*ncookies = 0;
 again:
	if (*readoff == DENT_DOT || *readoff == DENT_DOTDOT) {
		puffs_gendotdent(&dent, pn->pn_va.va_fileid, *readoff, reslen);
		(*readoff)++;
		PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff);
		goto again;
	}

	for (;;) {
		dfd_nth = dtfs_dirgetnth(pn->pn_data, DENT_ADJ(*readoff));
		if (!dfd_nth) {
			*eofflag = 1;
			break;
		}
		pn_nth = dfd_nth->dfd_node;

		if (!puffs_nextdent(&dent, dfd_nth->dfd_name,
		    pn_nth->pn_va.va_fileid,
		    puffs_vtype2dt(pn_nth->pn_va.va_type),
		    reslen))
			break;

		(*readoff)++;
		PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff);
	}

	return 0;
}
Example #2
0
File: null.c Project: glk/puffs
/*ARGSUSED*/
int
puffs_null_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc,
	struct dirent *de, off_t *off, size_t *reslen,
	const struct puffs_cred *pcred, int *eofflag, off_t *cookies,
	size_t *ncookies)
{
	struct puffs_node *pn = opc;
	struct dirent entry, *result;
	DIR *dp;
	off_t i;
	int rv;

	*ncookies = 0;
	dp = opendir(PNPATH(pn));
	if (dp == NULL)
		return errno;

	rv = 0;
	i = *off;

	/*
	 * XXX: need to do trickery here, telldir/seekdir would be nice, but
	 * then we'd need to keep state, which I'm too lazy to keep
	 */
	while (i--) {
		rv = readdir_r(dp, &entry, &result);
		if (rv || !result)
			goto out;
	}

	for (;;) {
		rv = readdir_r(dp, &entry, &result);
		if (rv != 0)
			goto out;

		if (!result) {
			*eofflag = 1;
			goto out;
		}

		if (_DIRENT_SIZE(result) > *reslen)
			goto out;

		*de = *result;
		*reslen -= _DIRENT_SIZE(result);
		de = _DIRENT_NEXT(de);

		(*off)++;
		PUFFS_STORE_DCOOKIE(cookies, ncookies, *off);
	}

 out:
	closedir(dp);
	return 0;
}
Example #3
0
int
sysctlfs_node_readdir(struct puffs_usermount *pu, void *opc,
	struct dirent *dent, off_t *readoff, size_t *reslen,
	const struct puffs_cred *pcr, int *eofflag,
	off_t *cookies, size_t *ncookies)
{
	struct sysctlnode sn[SFS_NODEPERDIR];
	struct sysctlnode qnode;
	struct puffs_node *pn_dir = opc;
	struct puffs_node *pn_res;
	struct puffs_pathobj po;
	struct sfsnode *sfs_dir = pn_dir->pn_data, *sfs_ent;
	SfsName *sname;
	size_t sl, i;
	enum vtype vt;
	ino_t id;

	*ncookies = 0;

 again:
	if (*readoff == DENT_DOT || *readoff == DENT_DOTDOT) {
		puffs_gendotdent(&dent, sfs_dir->myid, *readoff, reslen);
		(*readoff)++;
		PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff);
		goto again;
	}

	memset(&qnode, 0, sizeof(qnode));
	sl = SFS_NODEPERDIR * sizeof(struct sysctlnode);
	qnode.sysctl_flags = SYSCTL_VERSION;
	sname = PNPATH(pn_dir);
	(*sname)[PNPLEN(pn_dir)] = CTL_QUERY;

	if (sysctl(*sname, PNPLEN(pn_dir) + 1, sn, &sl,
	    &qnode, sizeof(qnode)) == -1)
		return ENOENT;

	po.po_path = sname;
	po.po_len = PNPLEN(pn_dir)+1;

	for (i = DENT_ADJ(*readoff); i < sl / sizeof(struct sysctlnode); i++) {
		if (SYSCTL_TYPE(sn[i].sysctl_flags) == CTLTYPE_NODE)
			vt = VDIR;
		else
			vt = VREG;

		/*
		 * check if the node exists.  if so, give it the real
		 * inode number.  otherwise just fake it.
		 */
		(*sname)[PNPLEN(pn_dir)] = sn[i].sysctl_num;
		pn_res = puffs_pn_nodewalk(pu, puffs_path_walkcmp, &po);
		if (pn_res) {
			sfs_ent = pn_res->pn_data;
			id = sfs_ent->myid;
		} else {
			id = nextid++;
		}

		if (!puffs_nextdent(&dent, sn[i].sysctl_name, id,
		    puffs_vtype2dt(vt), reslen))
			return 0;

		(*readoff)++;
		PUFFS_STORE_DCOOKIE(cookies, ncookies, *readoff);
	}

	*eofflag = 1;
	return 0;
}