示例#1
0
int
sysctlfs_node_lookup(struct puffs_usermount *pu, void *opc,
	struct puffs_newinfo *pni, const struct puffs_cn *pcn)
{
	struct puffs_cn *p2cn = __UNCONST(pcn); /* XXX: fix the interface */
	struct sysctlnode sn[SFS_NODEPERDIR];
	struct sysctlnode qnode;
	struct puffs_node *pn_dir = opc;
	struct puffs_node *pn_new;
	struct sfsnode *sfs_dir = pn_dir->pn_data, *sfs_new;
	SfsName *sname = PCNPATH(pcn);
	size_t sl, i;
	int nodetype;

	assert(ISADIR(sfs_dir));

	/*
	 * If we're looking for dotdot, we already have the entire pathname
	 * in sname, courtesy of pathbuild, so we can skip this step.
	 */
	if (!PCNISDOTDOT(pcn)) {
		memset(&qnode, 0, sizeof(qnode));
		sl = SFS_NODEPERDIR * sizeof(struct sysctlnode);
		qnode.sysctl_flags = SYSCTL_VERSION;
		(*sname)[PCNPLEN(pcn)] = CTL_QUERY;

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

		for (i = 0; i < sl / sizeof(struct sysctlnode); i++)
			if (strcmp(sn[i].sysctl_name, pcn->pcn_name) == 0)
				break;
		if (i == sl / sizeof(struct sysctlnode))
			return ENOENT;

		(*sname)[PCNPLEN(pcn)] = sn[i].sysctl_num;
		p2cn->pcn_po_full.po_len++;
		nodetype = sn[i].sysctl_flags;
	} else
		nodetype = CTLTYPE_NODE;

	pn_new = getnode(pu, &p2cn->pcn_po_full, nodetype);
	sfs_new = pn_new->pn_data;

	puffs_newinfo_setcookie(pni, pn_new);
	if (ISADIR(sfs_new))
		puffs_newinfo_setvtype(pni, VDIR);
	else
		puffs_newinfo_setvtype(pni, VREG);

	return 0;
}
示例#2
0
int
sysctlfs_node_read(struct puffs_usermount *pu, void *opc, uint8_t *buf,
	off_t offset, size_t *resid, const struct puffs_cred *pcr,
	int ioflag)
{
	char localbuf[SFS_MAXFILE];
	struct puffs_node *pn = opc;
	struct sfsnode *sfs = pn->pn_data;
	size_t sz = sizeof(localbuf);
	int xfer;

	if (ISADIR(sfs))
		return EISDIR;

	getnodedata(sfs, &pn->pn_po, localbuf, &sz);
	if ((ssize_t)sz < offset)
		xfer = 0;
	else
		xfer = MIN(*resid, sz - offset);

	if (xfer <= 0)
		return 0;

	memcpy(buf, localbuf + offset, xfer);
	*resid -= xfer;

	if (*resid && !rflag) {
		buf[xfer] = '\n';
		(*resid)--;
	}

	return 0;
}
示例#3
0
int
sysctlfs_node_getattr(struct puffs_usermount *pu, void *opc, struct vattr *va,
	const struct puffs_cred *pcr)
{
	struct puffs_node *pn = opc;
	struct sfsnode *sfs = pn->pn_data;

	memset(va, 0, sizeof(struct vattr));

	if (ISADIR(sfs)) {
		va->va_type = VDIR;
		va->va_mode = 0555;
	} else {
		va->va_type = VREG;
		va->va_mode = fileperms;
	}
	va->va_uid = fileuid;
	va->va_gid = filegid;
	va->va_nlink = getlinks(sfs, &pn->pn_po);
	va->va_fileid = sfs->myid;
	va->va_size = getsize(sfs, &pn->pn_po);
	va->va_gen = 1;
	va->va_rdev = PUFFS_VNOVAL;
	va->va_blocksize = 512;
	va->va_filerev = 1;

	va->va_atime = va->va_mtime = va->va_ctime = va->va_birthtime = fstime;

	return 0;
}
示例#4
0
int
sysctlfs_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
	struct puffs_newinfo *pni)
{
	struct puffs_pathobj po;
	struct puffs_node *pn;
	struct sfsnode *sfs;
	struct sfsfid *sfid;

	sfid = fid;

	po.po_len = sfid->len;
	po.po_path = &sfid->path;

	pn = getnode(pu, &po, 0);
	if (pn == NULL)
		return EINVAL;
	sfs = pn->pn_data;

	puffs_newinfo_setcookie(pni, pn);
	if (ISADIR(sfs))
		puffs_newinfo_setvtype(pni, VDIR);
	else
		puffs_newinfo_setvtype(pni, VREG);

	return 0;
}
示例#5
0
void					ft_ls(t_node *dir, int flags)
{
	DIR					*directory;
	struct dirent		*file;
	t_node				*dirs;
	t_node				*files;

	dirs = new_elem(FORBIDDEN_FILE, FORBIDDEN_FILE, 0);
	files = new_elem(FORBIDDEN_FILE, FORBIDDEN_FILE, 0);
	if ((!is_dir(dir->path, flags)))
	{
		render_file(dir, flags, NULL);
		return ;
	}
	if ((directory = opendir(dir->path)) == NULL)
	{
		perror("Error");
		return ;
	}
	while ((file = readdir(directory)) > 0 && (PUSH(files, file)) != NULL)
		if (ISADIR(file) && !IS(file->d_name, ".") &&
				!IS(file->d_name, "..") && RR_ON)
			PUSH(dirs, file);
	files = files->next;
	dirs = dirs->next;
	if ((ISHIDDEN(dir) && A_ON) || !ISHIDDEN(dir) || dir->first == TRUE)
		render_list(files, flags);
	free(files);
	closedir(directory);
	if (RR_ON)
		ft_ls_relaunch(dirs, flags);
	free(dirs);
}
示例#6
0
static int
getsize(struct sfsnode *sfs, struct puffs_pathobj *po)
{
	char buf[SFS_MAXFILE];
	size_t sz = sizeof(buf);

	if (ISADIR(sfs))
		return getlinks(sfs, po) * 16; /* totally arbitrary */

	getnodedata(sfs, po, buf, &sz);
	if (rflag)
		return sz;
	else
		return sz + 1; /* for \n, not \0 */
}
示例#7
0
static int
getlinks(struct sfsnode *sfs, struct puffs_pathobj *po)
{
	struct sysctlnode sn[SFS_NODEPERDIR];
	struct sysctlnode qnode;
	SfsName *sname;
	size_t sl;

	if (!ISADIR(sfs))
		return 1;

	memset(&qnode, 0, sizeof(qnode));
	sl = sizeof(sn);
	qnode.sysctl_flags = SYSCTL_VERSION;
	sname = po->po_path;
	(*sname)[po->po_len] = CTL_QUERY;

	if (sysctl(*sname, po->po_len + 1, sn, &sl,
	    &qnode, sizeof(qnode)) == -1)
		return 0;

	return (sl / sizeof(sn[0])) + 2;
}
示例#8
0
int
sysctlfs_node_write(struct puffs_usermount *pu, void *opc, uint8_t *buf,
	off_t offset, size_t *resid, const struct puffs_cred *cred,
	int ioflag)
{
	struct puffs_node *pn = opc;
	struct sfsnode *sfs = pn->pn_data;
	long long ll;
	int i, rv;
	bool b;

	/*
	 * I picked the wrong day to ... um, the wrong place to return errors
	 */

	/* easy to support, but just unavailable now */
	if (rflag)
		return EOPNOTSUPP;

	if (puffs_cred_isjuggernaut(cred) == 0)
		return EACCES;

	if (ISADIR(sfs))
		return EISDIR;

	if (offset != 0)
		return EINVAL;

	if (ioflag & PUFFS_IO_APPEND)
		return EINVAL;

	switch (SYSCTL_TYPE(sfs->sysctl_flags)) {
	case CTLTYPE_BOOL:
		if (strcasestr((const char *)buf, "true"))
			b = true;
		else if (strcasestr((const char *)buf, "false"))
			b = false;
		else
			return EINVAL;
		rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL,
		    &b, sizeof(b));
		break;
	case CTLTYPE_INT:
		if (sscanf((const char *)buf, "%d", &i) != 1)
			return EINVAL;
		rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL,
		    &i, sizeof(int));
		break;
	case CTLTYPE_QUAD:
		if (sscanf((const char *)buf, "%lld", &ll) != 1)
			return EINVAL;
		rv =  sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL,
		    &ll, sizeof(long long));
		break;
	case CTLTYPE_STRING:
		rv = sysctl(PNPATH(pn), PNPLEN(pn), NULL, NULL, buf, *resid);
		break;
	default:
		rv = EINVAL;
		break;
	}

	if (rv)
		return rv;

	*resid = 0;
	return 0;
}
示例#9
0
static void
getnodedata(struct sfsnode *sfs, struct puffs_pathobj *po,
	char *buf, size_t *bufsize)
{
	size_t sz;
	int error = 0;

	assert(!ISADIR(sfs));

	memset(buf, 0, *bufsize);
	switch (SYSCTL_TYPE(sfs->sysctl_flags)) {
	case CTLTYPE_BOOL: {
		bool b;
		sz = sizeof(bool);
		assert(sz <= *bufsize);
		if (sysctl(po->po_path, po->po_len, &b, &sz, NULL, 0) == -1) {
			error = errno;
			break;
		}
		if (rflag)
			memcpy(buf, &b, sz);
		else
			snprintf(buf, *bufsize, "%s", b ? "true" : "false");
		break;
	}
	case CTLTYPE_INT: {
		int i;
		sz = sizeof(int);
		assert(sz <= *bufsize);
		if (sysctl(po->po_path, po->po_len, &i, &sz, NULL, 0) == -1) {
			error = errno;
			break;
		}
		if (rflag)
			memcpy(buf, &i, sz);
		else
			snprintf(buf, *bufsize, "%d", i);
		break;
	}
	case CTLTYPE_QUAD: {
		quad_t q;
		sz = sizeof(q);
		assert(sz <= *bufsize);
		if (sysctl(po->po_path, po->po_len, &q, &sz, NULL, 0) == -1) {
			error = errno;
			break;
		}
		if (rflag)
			memcpy(buf, &q, sz);
		else
			snprintf(buf, *bufsize, "%" PRId64, q);
		break;
	}
	case CTLTYPE_STRUCT: {
		uint8_t snode[SFS_MAXFILE/2-1];
		unsigned i;

		sz = sizeof(snode);
		assert(sz <= *bufsize);
		if (sysctl(po->po_path, po->po_len, snode, &sz, NULL, 0) == -1){
			error = errno;
			break;
		}
		if (rflag) {
			memcpy(buf, &snode, sz);
		} else {
			for (i = 0; i < sz && 2*i < *bufsize; i++) {
				sprintf(&buf[2*i], "%02x", snode[i]);
			}
			buf[2*i] = '\0';
		}
		break;
	}
	case CTLTYPE_STRING: {
		sz = *bufsize;
		assert(sz <= *bufsize);
		if (sysctl(po->po_path, po->po_len, buf, &sz, NULL, 0) == -1) {
			error = errno;
			break;
		}
		break;
	}
	default:
		snprintf(buf, *bufsize, "invalid sysctl CTLTYPE %d",
		    SYSCTL_TYPE(sfs->sysctl_flags));
		break;
	}

	if (error) {
		*bufsize = 0;
		return;
	}

	if (rflag)
		*bufsize = sz;
	else
		*bufsize = strlen(buf);
}