/*ARGSUSED*/ int puffs_null_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va) { mode_t mode; int rv; mode = puffs_addvtype2mode(va->va_mode, va->va_type); switch (va->va_type) { case VFIFO: if (mkfifo(PCNPATH(pcn), mode) == -1) return errno; break; case VCHR: case VBLK: if (mknod(PCNPATH(pcn), mode, va->va_rdev) == -1) return errno; break; default: return EINVAL; } rv = makenode(pu, pni, pcn, va, 0); if (rv) unlink(PCNPATH(pcn)); return rv; }
/*ARGSUSED*/ int puffs_null_node_rename(struct puffs_usermount *pu, puffs_cookie_t opc, puffs_cookie_t src, const struct puffs_cn *pcn_src, puffs_cookie_t targ_dir, puffs_cookie_t targ, const struct puffs_cn *pcn_targ) { if (rename(PCNPATH(pcn_src), PCNPATH(pcn_targ)) == -1) return errno; return 0; }
/*ARGSUSED*/ int puffs_null_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va, const char *linkname) { int rv; if (symlink(linkname, PCNPATH(pcn)) == -1) return errno; rv = makenode(pu, pni, pcn, va, 0); if (rv) unlink(PCNPATH(pcn)); return rv; }
/*ARGSUSED*/ int puffs_null_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va) { int rv; if (mkdir(PCNPATH(pcn), va->va_mode) == -1) return errno; rv = makenode(pu, pni, pcn, va, 0); if (rv) rmdir(PCNPATH(pcn)); return rv; }
/*ARGSUSED*/ int puffs_null_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va) { int fd, rv; fd = open(PCNPATH(pcn), O_RDWR | O_CREAT | O_TRUNC); if (fd == -1) return errno; close(fd); rv = makenode(pu, pni, pcn, va, 1); if (rv) unlink(PCNPATH(pcn)); return rv; }
/*ARGSUSED*/ int puffs_null_node_link(struct puffs_usermount *pu, puffs_cookie_t opc, puffs_cookie_t targ, const struct puffs_cn *pcn) { struct puffs_node *pn_targ = targ; if (link(PNPATH(pn_targ), PCNPATH(pcn)) == -1) return errno; return 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; }
static int makenode(struct puffs_usermount *pu, struct puffs_newinfo *pni, const struct puffs_cn *pcn, const struct vattr *va, int regular) { struct puffs_node *pn; struct stat sb; int rv; if ((rv = processvattr(PCNPATH(pcn), va, regular)) != 0) return rv; pn = puffs_pn_new(pu, NULL); if (!pn) return ENOMEM; puffs_setvattr(&pn->pn_va, va); if (lstat(PCNPATH(pcn), &sb) == -1) return errno; puffs_stat2vattr(&pn->pn_va, &sb); puffs_newinfo_setcookie(pni, pn); return 0; }
int puffs_null_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, struct puffs_newinfo *pni, const struct puffs_cn *pcn) { struct puffs_node *pn = opc, *pn_res; struct stat sb; int rv; assert(pn->pn_va.va_type == VDIR); /* * Note to whoever is copypasting this: you must first check * if the node is there and only then do nodewalk. Alternatively * you could make sure that you don't return unlinked/rmdir'd * nodes in some other fashion */ rv = lstat(PCNPATH(pcn), &sb); if (rv) return errno; /* XXX2: nodewalk is a bit too slow here */ pn_res = puffs_pn_nodewalk(pu, inodecmp, &sb.st_ino); if (pn_res == NULL) { pn_res = puffs_pn_new(pu, NULL); if (pn_res == NULL) return ENOMEM; puffs_stat2vattr(&pn_res->pn_va, &sb); } puffs_newinfo_setcookie(pni, pn_res); puffs_newinfo_setvtype(pni, pn_res->pn_va.va_type); puffs_newinfo_setsize(pni, (off_t)pn_res->pn_va.va_size); puffs_newinfo_setrdev(pni, pn_res->pn_va.va_rdev); return 0; }