double Footholdtree::getedge(uint16_t curid, bool left) const { const Foothold& fh = getfh(curid); if (left) { uint16_t previd = fh.getprev(); if (!previd) return fh.getl(); const Foothold& prev = getfh(previd); previd = prev.getprev(); if (!previd) return prev.getl(); return walls.first(); } else { uint16_t nextid = fh.getnext(); if (!nextid) return fh.getr(); const Foothold& next = getfh(nextid); nextid = next.getnext(); if (!nextid) return next.getr(); return walls.second(); } }
void Footholdtree::limitmoves(PhysicsObject& phobj) const { if (phobj.hmobile()) { double crntx = phobj.crntx(); double nextx = phobj.nextx(); bool left = phobj.hspeed < 0.0f; double wall = getwall(phobj.fhid, left, phobj.nexty()); bool collision = left ? crntx >= wall && nextx <= wall : crntx <= wall && nextx >= wall; if (!collision && phobj.flagset(PhysicsObject::TURNATEDGES)) { wall = getedge(phobj.fhid, left); collision = left ? crntx >= wall && nextx <= wall : crntx <= wall && nextx >= wall; } if (collision) { phobj.limitx(wall); phobj.clearflag(PhysicsObject::TURNATEDGES); } } if (phobj.vmobile()) { double crnty = phobj.crnty(); double nexty = phobj.nexty(); auto ground = Range<double>( getfh(phobj.fhid).resolvex(phobj.crntx()), getfh(phobj.fhid).resolvex(phobj.nextx()) ); bool collision = crnty <= ground.first() && nexty >= ground.second(); if (collision) { phobj.limity(ground.second()); limitmoves(phobj); } else { if (nexty < borders.first()) { phobj.limity(borders.first()); } else if (nexty > borders.second()) { phobj.limity(borders.second()); } } } }
int getfh_main(int argc, char **argv) { int error; void *fh; size_t fh_size; if (argc < 2) return EXIT_FAILURE; #ifdef __FreeBSD__ fh_size = sizeof(fhandle_t); #else fh_size = 0; #endif fh = NULL; for (;;) { if (fh_size) { fh = malloc(fh_size); if (fh == NULL) { fprintf(stderr, "out of memory"); return EXIT_FAILURE; } } /* * The kernel provides the necessary size in fh_size - * but it may change if someone moves things around, * so retry untill we have enough memory. */ #ifdef __FreeBSD__ error = getfh(argv[1], fh); #else error = getfh(argv[1], fh, &fh_size); #endif if (error == 0) { break; } else { if (fh != NULL) free(fh); if (errno != E2BIG) { warn("getfh"); return EXIT_FAILURE; } } } error = write(STDOUT_FILENO, fh, fh_size); if (error == -1) { warn("write"); return EXIT_FAILURE; } free(fh); return 0; }
void Footholdtree::limitmoves(PhysicsObject& phobj, float dpfmult) const { float nextx = phobj.fx + phobj.hspeed * dpfmult; float nexty = phobj.fy + phobj.vspeed * dpfmult; if (nextx != phobj.fx) { vector2d<int32_t> vertical = vector2d<int32_t>(static_cast<int32_t>(phobj.fy - 40), static_cast<int32_t>(phobj.fy - 10)); float wall = getwall(phobj.fhid, phobj.hspeed < 0.0f, vertical); if ((phobj.hspeed < 0) ? nextx < wall : nextx > wall) { phobj.hspeed = 0.0f; } } if (nexty > phobj.fy) { float ground = getfh(phobj.fhid).resolvex(nextx); if (nexty >= ground && ground >= phobj.fy) { phobj.vspeed = 0.0f; phobj.fy = ground; } } }
static void fhb_fhget(char *filename, struct fhb_handle *handle) { int ret = 0; #if defined(HAVE_GETFH) && defined(HAVE_FHOPEN) { fhandle_t fh; ret = getfh(filename, &fh); if (ret) err(1, "getfh"); memcpy(handle, &fh, sizeof(fh)); } #endif { struct ViceIoctl vice_ioctl; vice_ioctl.in = NULL; vice_ioctl.in_size = 0; vice_ioctl.out = (caddr_t) handle; vice_ioctl.out_size = sizeof(*handle); ret = pioctl(filename, VIOC_FHGET, &vice_ioctl, 0); if (ret) errx(1, "k_pioctl"); } }
int main (int argc, char **argv) { int i; if (argc <= 1) { getfh ("."); getfh2 ("."); pstat ("."); pids ("."); } else for (i = 1; i < argc; i++) { getfh (argv[i]); getfh2 (argv[i]); pstat (argv[i]); pids (argv[i]); } return 0; }
int priv_vfs_fhopen_setup(int asroot, int injail, struct test *test) { setup_file("private_vfs_fhopen_setup: fpath", fpath, UID_ROOT, GID_WHEEL, 0644); fpath_initialized = 1; if (getfh(fpath, &fh) < 0) { warn("priv_vfs_fhopen_setup: getfh(%s)", fpath); return (-1); } return (0); }
int16_t Footholdtree::getgroundbelow(Point<int16_t> position) const { uint16_t fhid = getbelow(position.x(), position.y()); if (fhid > 0) { const Foothold& fh = getfh(fhid); return static_cast<int16_t>(fh.resolvex(position.x())); } else { return borders.second(); } }
void Footholdtree::updatefh(PhysicsObject& phobj) const { if (phobj.fhid == 0) { phobj.fhid = getbelow(phobj.fx, phobj.fy); } else if (phobj.onground) { const Foothold& curfh = getfh(phobj.fhid); if (phobj.fx > curfh.getr()) { phobj.fhid = getnext(phobj.fhid, false, phobj.fx, phobj.fy); } else if (phobj.fx < curfh.getl()) { phobj.fhid = getnext(phobj.fhid, true, phobj.fx, phobj.fy); } } else { phobj.fhid = getbelow(phobj.fx, phobj.fy); } const Foothold& nextfh = getfh(phobj.fhid); phobj.fhlayer = nextfh.getlayer(); phobj.fhslope = nextfh.getslope(); float ground = nextfh.resolvex(phobj.fx); if (phobj.vspeed == 0.0f) { if (abs(ground - phobj.fy) <= abs(phobj.hspeed)) { phobj.fy = ground; } } phobj.onground = phobj.fy == ground; }
void priv_vfs_getfh(int asroot, int injail, struct test *test) { fhandle_t fh; int error; error = getfh(fpath, &fh); if (asroot && injail) expect("priv_vfs_getfh(asroot, injail)", error, -1, EPERM); if (asroot && !injail) expect("priv_vfs_getfh(asroot, !injail)", error, 0, 0); if (!asroot && injail) expect("priv_vfs_getfh(!asroot, injail)", error, -1, EPERM); if (!asroot && !injail) expect("priv_vfs_getfh(!asroot, !injail)", error, -1, EPERM); }
int getfh_main(int argc, char **argv) { int error; fhandle_t fh; if (argc < 2) return EXIT_FAILURE; error = getfh(argv[1], &fh); if (error == 0) err(EXIT_FAILURE, "can not getfh"); error = write(STDOUT_FILENO, &fh, sizeof(fh)); if (error == -1) { perror("write"); return EXIT_FAILURE; } return 0; }
/*ARGSUSED*/ int puffs_null_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t opc, void *fid, size_t *fidsize) { struct puffs_node *pn = opc; fhandle_t fh; int rv; if (*fidsize != sizeof(struct fid)) return EINVAL; rv = 0; if (getfh(PNPATH(pn), &fh) == -1) rv = errno; if (rv == 0) { *(struct fid *)fid = fh.fh_fid; pn->pn_data = malloc(*fidsize); if (pn->pn_data == NULL) abort(); /* lazy */ memcpy(pn->pn_data, fid, *fidsize); } return rv; }
double Footholdtree::getwall(uint16_t curid, bool left, double fy) const { auto shorty = static_cast<int16_t>(fy); auto vertical = Range<int16_t>(shorty - 50, shorty - 1); if (left) { uint16_t previd = getfh(curid).getprev(); if (getfh(previd).iswall() && getfh(previd).getver().overlaps(vertical)) { return getfh(curid).getl(); } previd = getfh(previd).getprev(); if (getfh(previd).iswall() && getfh(previd).getver().overlaps(vertical)) { return getfh(previd).getl(); } return walls.first(); } else { uint16_t nextid = getfh(curid).getnext(); if (getfh(nextid).iswall() && getfh(nextid).getver().overlaps(vertical)) { return getfh(curid).getr(); } nextid = getfh(nextid).getnext(); if (getfh(nextid).iswall() && getfh(nextid).getver().overlaps(vertical)) { return getfh(nextid).getr(); } return walls.second(); } }
void Footholdtree::updatefh(PhysicsObject& phobj) const { const Foothold& curfh = getfh(phobj.fhid); bool checkslope = false; double x = phobj.crntx(); double y = phobj.crnty(); if (phobj.onground) { if (std::floor(x) > curfh.getr()) { phobj.fhid = curfh.getnext(); } else if (std::ceil(x) < curfh.getl()) { phobj.fhid = curfh.getprev(); } if (phobj.fhid == 0) { phobj.fhid = getbelow(x, y); } else { checkslope = true; } } else { phobj.fhid = getbelow(x, y); } const Foothold& nextfh = getfh(phobj.fhid); phobj.fhslope = nextfh.getslope(); double ground = nextfh.resolvex(x); if (phobj.vspeed == 0.0 && checkslope) { double vdelta = abs(phobj.fhslope); if (phobj.fhslope < 0.0) { vdelta *= (ground - y); } else if (phobj.fhslope > 0.0) { vdelta *= (y - ground); } if (curfh.getslope() != 0.0 || nextfh.getslope() != 0.0) { if (phobj.hspeed > 0.0 && vdelta <= phobj.hspeed) { phobj.y = ground; } else if (phobj.hspeed < 0.0 && vdelta >= phobj.hspeed) { phobj.y = ground; } } } phobj.onground = phobj.y == ground; uint16_t belowid = getbelow(x, nextfh.resolvex(x) + 1.0); if (belowid > 0) { double nextground = getfh(belowid).resolvex(x); phobj.enablejd = (nextground - ground) < 600.0; phobj.groundbelow = ground + 1.0; } else { phobj.enablejd = false; } if (phobj.fhlayer == 0 || phobj.onground) { phobj.fhlayer = nextfh.getlayer(); } }
static struct nfs_fh_len * get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret, mountstat3 *error, int v3) { struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt); struct stat stb, estb; nfs_export *exp; struct nfs_fh_len *fh; char rpath[MAXPATHLEN+1]; char *p = *path; if (*p == '\0') p = "/"; /* Reload /var/lib/nfs/etab if necessary */ auth_reload(); /* Resolve symlinks */ if (realpath(p, rpath) != NULL) { rpath[sizeof (rpath) - 1] = '\0'; p = rpath; } /* Now authenticate the intruder... */ exp = auth_authenticate("mount", sin, p); if (!exp) { *error = NFSERR_ACCES; return NULL; } if (stat(p, &stb) < 0) { xlog(L_WARNING, "can't stat exported dir %s: %s", p, strerror(errno)); if (errno == ENOENT) *error = NFSERR_NOENT; else *error = NFSERR_ACCES; return NULL; } if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) { xlog(L_WARNING, "%s is not a directory or regular file", p); *error = NFSERR_NOTDIR; return NULL; } if (stat(exp->m_export.e_path, &estb) < 0) { xlog(L_WARNING, "can't stat export point %s: %s", p, strerror(errno)); *error = NFSERR_NOENT; return NULL; } if (estb.st_dev != stb.st_dev && (!new_cache || !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT))) { xlog(L_WARNING, "request to export directory %s below nearest filesystem %s", p, exp->m_export.e_path); *error = NFSERR_ACCES; return NULL; } if (exp->m_export.e_mountpoint && !is_mountpoint(exp->m_export.e_mountpoint[0]? exp->m_export.e_mountpoint: exp->m_export.e_path)) { xlog(L_WARNING, "request to export an unmounted filesystem: %s", p); *error = NFSERR_NOENT; return NULL; } if (new_cache) { /* This will be a static private nfs_export with just one * address. We feed it to kernel then extract the filehandle, * */ if (cache_export(exp, p)) { *error = NFSERR_ACCES; return NULL; } fh = cache_get_filehandle(exp, v3?64:32, p); if (fh == NULL) { *error = NFSERR_ACCES; return NULL; } } else { int did_export = 0; retry: if (exp->m_exported<1) { export_export(exp); did_export = 1; } if (!exp->m_xtabent) xtab_append(exp); if (v3) fh = getfh_size ((struct sockaddr *) sin, p, 64); if (!v3 || (fh == NULL && errno == EINVAL)) { /* We first try the new nfs syscall. */ fh = getfh ((struct sockaddr *) sin, p); if (fh == NULL && errno == EINVAL) /* Let's try the old one. */ fh = getfh_old ((struct sockaddr *) sin, stb.st_dev, stb.st_ino); } if (fh == NULL && !did_export) { exp->m_exported = 0; goto retry; } if (fh == NULL) { xlog(L_WARNING, "getfh failed: %s", strerror(errno)); *error = NFSERR_ACCES; return NULL; } } *error = NFS_OK; mountlist_add(inet_ntoa(sin->sin_addr), p); if (expret) *expret = exp; return fh; }
/* * The mount rpc service */ void mntsrv(struct svc_req *rqstp, SVCXPRT *transp) { char rpcpath[RPCMNT_PATHLEN+1], dirpath[MAXPATHLEN]; struct hostent *hp = NULL; struct exportlist *ep; sigset_t sighup_mask; int defset, hostset; struct fhreturn fhr; struct dirlist *dp; struct statfs fsb; struct stat stb; in_addr_t saddr; u_short sport; long bad = 0; sigemptyset(&sighup_mask); sigaddset(&sighup_mask, SIGHUP); saddr = transp->xp_raddr.sin_addr.s_addr; sport = ntohs(transp->xp_raddr.sin_port); switch (rqstp->rq_proc) { case NULLPROC: if (!svc_sendreply(transp, xdr_void, NULL)) syslog(LOG_ERR, "Can't send reply"); return; case RPCMNT_MOUNT: if (debug) fprintf(stderr, "Got mount request from %s\n", inet_ntoa(transp->xp_raddr.sin_addr)); if (sport >= IPPORT_RESERVED && resvport_only) { syslog(LOG_NOTICE, "Refused mount RPC from host %s port %d", inet_ntoa(transp->xp_raddr.sin_addr), sport); svcerr_weakauth(transp); return; } if (!svc_getargs(transp, xdr_dir, rpcpath)) { svcerr_decode(transp); return; } if (debug) fprintf(stderr, "rpcpath: %s\n", rpcpath); /* * Get the real pathname and make sure it is a file or * directory that exists. */ if (realpath(rpcpath, dirpath) == NULL) { bad = errno; if (debug) fprintf(stderr, "realpath failed on %s\n", rpcpath); strlcpy(dirpath, rpcpath, sizeof(dirpath)); } else if (stat(dirpath, &stb) < 0 || (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) || statfs(dirpath, &fsb) < 0) { if (debug) fprintf(stderr, "stat failed on %s\n", dirpath); bad = ENOENT; /* We will send error reply later */ } /* Check in the exports list */ sigprocmask(SIG_BLOCK, &sighup_mask, NULL); ep = ex_search(&fsb.f_fsid); hostset = defset = 0; if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset) || ((dp = dirp_search(ep->ex_dirl, dirpath)) && chk_host(dp, saddr, &defset, &hostset)) || (defset && scan_tree(ep->ex_defdir, saddr) == 0 && scan_tree(ep->ex_dirl, saddr) == 0))) { if (bad) { if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) syslog(LOG_ERR, "Can't send reply"); sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); return; } if (hostset & DP_HOSTSET) fhr.fhr_flag = hostset; else fhr.fhr_flag = defset; fhr.fhr_vers = rqstp->rq_vers; /* Get the file handle */ memset(&fhr.fhr_fh, 0, sizeof(nfsfh_t)); if (getfh(dirpath, (fhandle_t *)&fhr.fhr_fh) < 0) { if (errno == ENOSYS) { syslog(LOG_ERR, "Kernel does not support NFS exporting, " "mountd aborting.."); _exit(1); } bad = errno; syslog(LOG_ERR, "Can't get fh for %s", dirpath); if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) syslog(LOG_ERR, "Can't send reply"); sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); return; } if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&fhr)) syslog(LOG_ERR, "Can't send reply"); if (hp == NULL) hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); if (hp) add_mlist(hp->h_name, dirpath); else add_mlist(inet_ntoa(transp->xp_raddr.sin_addr), dirpath); if (debug) { fprintf(stderr, "Mount successful for %s by %s.\n", dirpath, inet_ntoa(transp->xp_raddr.sin_addr)); } } else bad = EACCES; if (bad && !svc_sendreply(transp, xdr_long, (caddr_t)&bad)) syslog(LOG_ERR, "Can't send reply"); sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL); return; case RPCMNT_DUMP: if (!svc_sendreply(transp, xdr_mlist, NULL)) syslog(LOG_ERR, "Can't send reply"); return; case RPCMNT_UMOUNT: if (sport >= IPPORT_RESERVED && resvport_only) { svcerr_weakauth(transp); return; } if (!svc_getargs(transp, xdr_dir, dirpath)) { svcerr_decode(transp); return; } if (!svc_sendreply(transp, xdr_void, NULL)) syslog(LOG_ERR, "Can't send reply"); hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); if (hp) del_mlist(hp->h_name, dirpath); del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), dirpath); return; case RPCMNT_UMNTALL: if (sport >= IPPORT_RESERVED && resvport_only) { svcerr_weakauth(transp); return; } if (!svc_sendreply(transp, xdr_void, NULL)) syslog(LOG_ERR, "Can't send reply"); hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET); if (hp) del_mlist(hp->h_name, NULL); del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), NULL); return; case RPCMNT_EXPORT: if (!svc_sendreply(transp, xdr_explist, NULL)) syslog(LOG_ERR, "Can't send reply"); return; default: svcerr_noproc(transp); return; } }