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; }
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; }
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; }
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; }
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); }
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 */ }
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; }
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; }
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); }