From b2438a4a0884f0f45e838da5e38afd5ada7fa688 Mon Sep 17 00:00:00 2001 From: Eirikr Hinngart <151315375+Oichkatzelesfrettschen@users.noreply.github.com> Date: Fri, 30 May 2025 11:42:24 -0700 Subject: [PATCH] Remove 50 NetBSD-related files --- lib/libpuffs/Makefile | 32 - lib/libpuffs/TODO | 42 -- lib/libpuffs/callcontext.c | 372 ---------- lib/libpuffs/creds.c | 260 ------- lib/libpuffs/dispatcher.c | 1209 --------------------------------- lib/libpuffs/flush.c | 135 ---- lib/libpuffs/framebuf.c | 1069 ----------------------------- lib/libpuffs/null.c | 683 ------------------- lib/libpuffs/opdump.c | 542 --------------- lib/libpuffs/paths.c | 299 -------- lib/libpuffs/pnode.c | 216 ------ lib/libpuffs/puffs.3 | 593 ---------------- lib/libpuffs/puffs.c | 1123 ------------------------------ lib/libpuffs/puffs.h | 737 -------------------- lib/libpuffs/puffs_cc.3 | 94 --- lib/libpuffs/puffs_cred.3 | 167 ----- lib/libpuffs/puffs_flush.3 | 113 --- lib/libpuffs/puffs_framebuf.3 | 620 ----------------- lib/libpuffs/puffs_node.3 | 101 --- lib/libpuffs/puffs_ops.3 | 955 -------------------------- lib/libpuffs/puffs_path.3 | 125 ---- lib/libpuffs/puffs_priv.h | 278 -------- lib/libpuffs/puffsdump.h | 68 -- lib/libpuffs/requests.c | 239 ------- lib/libpuffs/shlib_version | 4 - lib/libpuffs/subr.c | 321 --------- lib/libpuffs/suspend.c | 49 -- lib/librmt/Makefile | 23 - lib/librmt/README | 20 - lib/librmt/pathnames.h | 30 - lib/librmt/rmtlib.c | 896 ------------------------ lib/librmt/rmtops.3 | 182 ----- lib/libtelnet/Makefile | 38 -- lib/libtelnet/auth-proto.h | 103 --- lib/libtelnet/auth.c | 617 ----------------- lib/libtelnet/auth.h | 80 --- lib/libtelnet/enc-proto.h | 140 ---- lib/libtelnet/enc_des.c | 665 ------------------ lib/libtelnet/encrypt.c | 960 -------------------------- lib/libtelnet/encrypt.h | 101 --- lib/libtelnet/genget.c | 105 --- lib/libtelnet/getent.c | 76 --- lib/libtelnet/kerberos5.c | 731 -------------------- lib/libtelnet/key-proto.h | 63 -- lib/libtelnet/misc-proto.h | 72 -- lib/libtelnet/misc.c | 93 --- lib/libtelnet/misc.h | 46 -- lib/libtelnet/pk.c | 292 -------- lib/libtelnet/shlib_version | 5 - lib/libtelnet/spx.c | 594 ---------------- 50 files changed, 16378 deletions(-) delete mode 100644 lib/libpuffs/Makefile delete mode 100644 lib/libpuffs/TODO delete mode 100644 lib/libpuffs/callcontext.c delete mode 100644 lib/libpuffs/creds.c delete mode 100644 lib/libpuffs/dispatcher.c delete mode 100644 lib/libpuffs/flush.c delete mode 100644 lib/libpuffs/framebuf.c delete mode 100644 lib/libpuffs/null.c delete mode 100644 lib/libpuffs/opdump.c delete mode 100644 lib/libpuffs/paths.c delete mode 100644 lib/libpuffs/pnode.c delete mode 100644 lib/libpuffs/puffs.3 delete mode 100644 lib/libpuffs/puffs.c delete mode 100644 lib/libpuffs/puffs.h delete mode 100644 lib/libpuffs/puffs_cc.3 delete mode 100644 lib/libpuffs/puffs_cred.3 delete mode 100644 lib/libpuffs/puffs_flush.3 delete mode 100644 lib/libpuffs/puffs_framebuf.3 delete mode 100644 lib/libpuffs/puffs_node.3 delete mode 100644 lib/libpuffs/puffs_ops.3 delete mode 100644 lib/libpuffs/puffs_path.3 delete mode 100644 lib/libpuffs/puffs_priv.h delete mode 100644 lib/libpuffs/puffsdump.h delete mode 100644 lib/libpuffs/requests.c delete mode 100644 lib/libpuffs/shlib_version delete mode 100644 lib/libpuffs/subr.c delete mode 100644 lib/libpuffs/suspend.c delete mode 100644 lib/librmt/Makefile delete mode 100644 lib/librmt/README delete mode 100644 lib/librmt/pathnames.h delete mode 100644 lib/librmt/rmtlib.c delete mode 100644 lib/librmt/rmtops.3 delete mode 100644 lib/libtelnet/Makefile delete mode 100644 lib/libtelnet/auth-proto.h delete mode 100644 lib/libtelnet/auth.c delete mode 100644 lib/libtelnet/auth.h delete mode 100644 lib/libtelnet/enc-proto.h delete mode 100644 lib/libtelnet/enc_des.c delete mode 100644 lib/libtelnet/encrypt.c delete mode 100644 lib/libtelnet/encrypt.h delete mode 100644 lib/libtelnet/genget.c delete mode 100644 lib/libtelnet/getent.c delete mode 100644 lib/libtelnet/kerberos5.c delete mode 100644 lib/libtelnet/key-proto.h delete mode 100644 lib/libtelnet/misc-proto.h delete mode 100644 lib/libtelnet/misc.c delete mode 100644 lib/libtelnet/misc.h delete mode 100644 lib/libtelnet/pk.c delete mode 100644 lib/libtelnet/shlib_version delete mode 100644 lib/libtelnet/spx.c diff --git a/lib/libpuffs/Makefile b/lib/libpuffs/Makefile deleted file mode 100644 index c43a4c710..000000000 --- a/lib/libpuffs/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# $NetBSD: Makefile,v 1.25 2012/03/21 05:37:43 matt Exp $ -# - -.include - -USE_FORT?= yes # data-driven bugs? - -WARNS?= 5 - -LIB= puffs - -SRCS= puffs.c callcontext.c creds.c \ - paths.c pnode.c \ - subr.c -MAN= puffs.3 puffs_cc.3 puffs_cred.3 puffs_flush.3 \ - puffs_framebuf.3 puffs_node.3 puffs_ops.3 puffs_path.3 -INCS= puffs.h -INCSDIR= /usr/include -LINTFLAGS+=-S -w - -.if defined(__MINIX) -.PATH: ${NETBSDSRCDIR}/minix/lib/libpuffs -SRCS+= inode.c link.c main.c misc.c mount.c open.c path.c \ - protect.c read.c stadir.c time.c utility.c \ - table.c - -CPPFLAGS+= -D_MINIX_SYSTEM -I${.CURDIR} -I${NETBSDSRCDIR}/minix/lib/libpuffs - -NOGCCERROR=yes -.endif # defined(__MINIX) - -.include diff --git a/lib/libpuffs/TODO b/lib/libpuffs/TODO deleted file mode 100644 index 0a5e3e28e..000000000 --- a/lib/libpuffs/TODO +++ /dev/null @@ -1,42 +0,0 @@ - $NetBSD: TODO,v 1.3 2007/07/19 07:48:10 pooka Exp $ - -Document some possible user-visible changes that may take place. -For a complete list, please dump my brain and excavate. - - * figure out what do to with struct vattr, maybe introduce some - vattr-like puffs-specific structure (translation costs?) instead - of direct exposure - - * make puffs_node opaque outside the library - - * make it possible to cache symlink names and getattr results in - the kernel ... although I'm not as critically concerned with the - kernel caching as I am with userlevel caching - - * try to implement a kernel policy for VOP_ACCESS, it's called - very very often - but this requires some kernel caching - - + also try to figure out how to implement it in cases where it's - more difficult to do, e.g. how can we know readdir on sshfs will - fail without actually trying to read the directory? If we fail - readdir itself, it's treated as success - - * implement file system layering .. this will most likely bring - massive changes to how the ops vector is handled, for instance. - pcc/pu division should stay quite like the way it is now, but - maybe there will be layer specific ops. - - * make puffs more like kernel vfs - or make kernel vfs more like puffs - - * decide what to do about setback operations. they kind of violate - the transparency of FAF for op handling - - * remove flags parameter to puffs_init and replace with something - more generic - - * fix incoming requests to not require memcpy with continuations - (not user-visible?) - - * make continuations play with libpthread, lib/36011 (not user-visible?) - - * clean up the request dispatching / continuation code (not user-visible?) diff --git a/lib/libpuffs/callcontext.c b/lib/libpuffs/callcontext.c deleted file mode 100644 index a6a21d993..000000000 --- a/lib/libpuffs/callcontext.c +++ /dev/null @@ -1,372 +0,0 @@ -/* $NetBSD: callcontext.c,v 1.27 2011/12/06 21:15:39 skrll Exp $ */ - -/* - * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Research Foundation of Helsinki University of Technology - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: callcontext.c,v 1.27 2011/12/06 21:15:39 skrll Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -#if 0 -#define DPRINTF(x) printf x -#else -#define DPRINTF(x) -#endif - -/* - * Set the following to 1 to not handle each request on a separate - * stack. This is highly volatile kludge, therefore no external - * interface. - */ -int puffs_fakecc; - -/* - * user stuff - */ - -/* - * So, we need to get back to where we came from. This can happen in two - * different ways: - * 1) PCC_MLCONT is set, in which case we need to go to the mainloop - * 2) It is not set, and we simply jump to pcc_uc_ret. - */ -void -puffs_cc_yield(struct puffs_cc *pcc) -{ - struct puffs_cc *jumpcc; - int rv; - - assert(puffs_fakecc == 0); - - if ((~pcc->pcc_flags & (PCC_BORROWED|PCC_DONE)) == 0) { - pcc->pcc_flags &= ~(PCC_BORROWED|PCC_DONE); - /* - * see the XXX comment in puffs__cc_cont - */ - puffs__cc_destroy(pcc, 1); - setcontext(&pcc->pcc_uc_ret); - } - pcc->pcc_flags &= ~PCC_BORROWED; - - /* romanes eunt domus */ - DPRINTF(("puffs_cc_yield: ")); - if ((pcc->pcc_flags & PCC_MLCONT) == 0) { - DPRINTF(("no mlcont, pcc %p\n", pcc)); - swapcontext(&pcc->pcc_uc, &pcc->pcc_uc_ret); - } else { - DPRINTF(("mlcont, pcc %p\n", pcc)); - pcc->pcc_flags &= ~PCC_MLCONT; - rv = puffs__cc_create(pcc->pcc_pu, puffs__theloop, &jumpcc); - if (rv) - abort(); /* p-p-p-pa-pa-panic (XXX: fixme) */ - swapcontext(&pcc->pcc_uc, &jumpcc->pcc_uc); - DPRINTF(("puffs_cc_yield: post swap pcc %p\n", pcc)); - } -} - -/* - * Internal continue routine. This has slightly different semantics. - * We simply make our cc available in the freelist and jump to the - * indicated pcc. - */ -void -puffs__cc_cont(struct puffs_cc *pcc) -{ - struct puffs_cc *mycc; - - mycc = puffs_cc_getcc(pcc->pcc_pu); - DPRINTF(("puffs__cc_cont: pcc %p, mycc %p\n", pcc, mycc)); - - /* - * XXX: race between setcontext() and recycle if - * we go multithreaded - */ - puffs__cc_destroy(mycc, 1); - pcc->pcc_flags |= PCC_MLCONT; - setcontext(&pcc->pcc_uc); -} - -void -puffs_cc_continue(struct puffs_cc *pcc) -{ - - /* ramble on */ - DPRINTF(("puffs_cc_continue: pcc %p\n", pcc)); - if (puffs_fakecc) { - pcc->pcc_func(pcc->pcc_farg); - } else { - swapcontext(&pcc->pcc_uc_ret, &pcc->pcc_uc); - } -} - -/* - * "Borrows" pcc, *NOT* called from pcc owner. Acts like continue. - * So the idea is to use this, give something the context back to - * run to completion and then jump back to where ever this was called - * from after the op dispatching is complete (or if the pcc decides to - * yield again). - */ -void -puffs__goto(struct puffs_cc *loanpcc) -{ - - loanpcc->pcc_flags |= PCC_BORROWED; - - swapcontext(&loanpcc->pcc_uc_ret, &loanpcc->pcc_uc); -} - -void -puffs_cc_schedule(struct puffs_cc *pcc) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - - assert(pu->pu_state & PU_INLOOP); - TAILQ_INSERT_TAIL(&pu->pu_sched, pcc, pcc_schedent); -} - -int -puffs_cc_getcaller(struct puffs_cc *pcc, pid_t *pid, lwpid_t *lid) -{ - - if ((pcc->pcc_flags & PCC_HASCALLER) == 0) { - errno = ESRCH; - return -1; - } - - if (pid) - *pid = pcc->pcc_pid; - if (lid) - *lid = pcc->pcc_lid; - return 0; -} - -static struct puffs_cc fakecc; - -static struct puffs_cc * -slowccalloc(struct puffs_usermount *pu) -{ - struct puffs_cc *volatile pcc; - void *sp; - size_t stacksize = 1<pu_cc_stackshift; -#if !defined(__minix) - const long psize = sysconf(_SC_PAGESIZE); -#endif /* !defined(__minix) */ - - if (puffs_fakecc) - return &fakecc; - - sp = mmap(NULL, stacksize, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE|MAP_ALIGNED(pu->pu_cc_stackshift), -1, 0); - if (sp == MAP_FAILED) - return NULL; - - pcc = sp; - memset(pcc, 0, sizeof(struct puffs_cc)); - -#if !defined(__minix) -#ifndef __MACHINE_STACK_GROWS_UP - mprotect((uint8_t *)sp + psize, (size_t)psize, PROT_NONE); -#else - mprotect((uint8_t *)sp + stacksize - psize, (size_t)psize, PROT_NONE); -#endif -#endif /* !defined(__minix) */ - - /* initialize both ucontext's */ - if (getcontext(&pcc->pcc_uc) == -1) { - munmap(pcc, stacksize); - return NULL; - } - if (getcontext(&pcc->pcc_uc_ret) == -1) { - munmap(pcc, stacksize); - return NULL; - } - - return pcc; -} - -int -puffs__cc_create(struct puffs_usermount *pu, puffs_ccfunc func, - struct puffs_cc **pccp) -{ - struct puffs_cc *pcc; - size_t stacksize = 1<pu_cc_stackshift; - stack_t *st; - - /* Do we have a cached copy? */ - if (pu->pu_cc_nstored == 0) { - pcc = slowccalloc(pu); - if (pcc == NULL) - return -1; - pcc->pcc_pu = pu; - DPRINTF(("puffs__cc_create: allocated pcc %p\n", pcc)); - } else { - pcc = LIST_FIRST(&pu->pu_ccmagazin); - assert(pcc != NULL); - - LIST_REMOVE(pcc, pcc_rope); - pu->pu_cc_nstored--; - DPRINTF(("puffs__cc_create: magazin pcc %p\n", pcc)); - } - assert(pcc->pcc_pu == pu); - - if (puffs_fakecc) { - pcc->pcc_func = func; - pcc->pcc_farg = pcc; - } else { - const long psize = sysconf(_SC_PAGESIZE); - - /* link context */ - pcc->pcc_uc.uc_link = &pcc->pcc_uc_ret; - - /* setup stack - * - * XXX: I guess this should theoretically be preserved by - * swapcontext(). However, it gets lost. So reinit it. - */ - st = &pcc->pcc_uc.uc_stack; - st->ss_sp = ((uint8_t *)(void *)pcc) + psize; - st->ss_size = stacksize - psize; - st->ss_flags = 0; - - /* - * Give us an initial context to jump to. - * - * Our manual page says that portable code shouldn't - * rely on being able to pass pointers through makecontext(). - * kjk says that NetBSD code doesn't need to worry about this. - * uwe says it would be like putting a "keep away from - * children" sign on a box of toys. - */ - makecontext(&pcc->pcc_uc, (void *)func, 1, (uintptr_t)pcc); - } - - *pccp = pcc; - return 0; -} - -void -puffs__cc_setcaller(struct puffs_cc *pcc, pid_t pid, lwpid_t lid) -{ - - pcc->pcc_pid = pid; - pcc->pcc_lid = lid; - pcc->pcc_flags |= PCC_HASCALLER; -} - -static void -cc_free(struct puffs_cc *pcc) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - size_t stacksize = 1<pu_cc_stackshift; - - DPRINTF(("invalidating pcc %p\n", pcc)); - assert(!puffs_fakecc); - munmap(pcc, stacksize); -} - -void -puffs__cc_destroy(struct puffs_cc *pcc, int nonuke) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - - pcc->pcc_flags &= ~PCC_HASCALLER; - assert(pcc->pcc_flags == 0); - assert(!puffs_fakecc); - - /* not over limit? stuff away in the store, otherwise nuke */ - if (nonuke || pu->pu_cc_nstored < PUFFS_CCMAXSTORE) { - pcc->pcc_pb = NULL; - DPRINTF(("puffs__cc_destroy: storing pcc %p\n", pcc)); - LIST_INSERT_HEAD(&pu->pu_ccmagazin, pcc, pcc_rope); - pu->pu_cc_nstored++; - } else { - cc_free(pcc); - } -} - -void -puffs__cc_exit(struct puffs_usermount *pu) -{ - struct puffs_cc *pcc; - - while ((pcc = LIST_FIRST(&pu->pu_ccmagazin)) != NULL) { - LIST_REMOVE(pcc, pcc_rope); - cc_free(pcc); - } -} - -struct puffs_cc * -puffs_cc_getcc(struct puffs_usermount *pu) -{ - size_t stacksize = 1<pu_cc_stackshift; - uintptr_t bottom; - - if (puffs_fakecc) - return &fakecc; - - bottom = ((uintptr_t)&bottom) & ~(stacksize-1); - return (struct puffs_cc *)bottom; -} - -int -puffs__cc_savemain(struct puffs_usermount *pu) -{ - - if (puffs_fakecc) - return 0; - - PU_CLRSFLAG(pu, PU_MAINRESTORE); - return getcontext(&pu->pu_mainctx); -} - -int -puffs__cc_restoremain(struct puffs_usermount *pu) -{ - - if (puffs_fakecc) - return 0; - - puffs__cc_destroy(puffs_cc_getcc(pu), 1); - PU_SETSFLAG(pu, PU_MAINRESTORE); - return setcontext(&pu->pu_mainctx); -} diff --git a/lib/libpuffs/creds.c b/lib/libpuffs/creds.c deleted file mode 100644 index e103bb9b4..000000000 --- a/lib/libpuffs/creds.c +++ /dev/null @@ -1,260 +0,0 @@ -/* $NetBSD: creds.c,v 1.16 2012/03/15 12:49:36 njoly Exp $ */ - -/* - * Copyright (c) 2006 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the Ulla Tuominen Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: creds.c,v 1.16 2012/03/15 12:49:36 njoly Exp $"); -#endif /* !lint */ - -/* - * Interface for dealing with credits. - */ - -#include -#include - -#include -#include -#include -#include - -#include "puffs_priv.h" - -#define UUCCRED(a) (a->pkcr_type == PUFFCRED_TYPE_UUC) -#define INTCRED(a) (a->pkcr_type == PUFFCRED_TYPE_INTERNAL) - -int -puffs_cred_getuid(const struct puffs_cred *pcr, uid_t *ruid) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - - if (!UUCCRED(pkcr)) { - errno = EOPNOTSUPP; - return -1; - } - *ruid = pkcr->pkcr_uuc.cr_uid; - - return 0; -} - -int -puffs_cred_getgid(const struct puffs_cred *pcr, gid_t *rgid) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - - if (!UUCCRED(pkcr)) { - errno = EOPNOTSUPP; - return -1; - } - *rgid = pkcr->pkcr_uuc.cr_gid; - - return 0; -} - -int -puffs_cred_getgroups(const struct puffs_cred *pcr, gid_t *rgids, short *ngids) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - size_t ncopy; - - if (!UUCCRED(pkcr)) { - errno = EOPNOTSUPP; - *ngids = 0; - return -1; - } - - ncopy = MIN(*ngids, pkcr->pkcr_uuc.cr_ngroups); - (void)memcpy(rgids, pkcr->pkcr_uuc.cr_groups, sizeof(gid_t) * ncopy); - *ngids = (short)ncopy; - - return 0; -} - -bool -puffs_cred_isuid(const struct puffs_cred *pcr, uid_t uid) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - - return UUCCRED(pkcr) && pkcr->pkcr_uuc.cr_uid == uid; -} - -bool -puffs_cred_hasgroup(const struct puffs_cred *pcr, gid_t gid) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - short i; - - if (!UUCCRED(pkcr)) - return false; - - if (pkcr->pkcr_uuc.cr_gid == gid) - return true; - for (i = 0; i < pkcr->pkcr_uuc.cr_ngroups; i++) - if (pkcr->pkcr_uuc.cr_groups[i] == gid) - return true; - - return false; -} - -bool -puffs_cred_isregular(const struct puffs_cred *pcr) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - - return UUCCRED(pkcr); -} - -bool -puffs_cred_iskernel(const struct puffs_cred *pcr) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - - return INTCRED(pkcr) && pkcr->pkcr_internal == PUFFCRED_CRED_NOCRED; -} - -bool -puffs_cred_isfs(const struct puffs_cred *pcr) -{ - PUFFS_MAKEKCRED(pkcr, pcr); - - return INTCRED(pkcr) && pkcr->pkcr_internal == PUFFCRED_CRED_FSCRED; -} - -bool -puffs_cred_isjuggernaut(const struct puffs_cred *pcr) -{ - - return puffs_cred_isuid(pcr, 0) || puffs_cred_iskernel(pcr) - || puffs_cred_isfs(pcr); -} - -/* - * Generic routine for checking file access rights. Modeled after - * vaccess() in the kernel. - */ -int -puffs_access(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, - mode_t acc_mode, const struct puffs_cred *pcr) -{ - mode_t mask; - - /* megapower */ - if (puffs_cred_iskernel(pcr) || puffs_cred_isfs(pcr)) - return 0; - - /* superuser, allow all except exec if *ALL* exec bits are unset */ - if (puffs_cred_isuid(pcr, 0)) { - if ((acc_mode & PUFFS_VEXEC) && type != VDIR && - (file_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) - return EACCES; - return 0; - } - - mask = 0; - /* owner */ - if (puffs_cred_isuid(pcr, uid)) { - if (acc_mode & PUFFS_VEXEC) - mask |= S_IXUSR; - if (acc_mode & PUFFS_VREAD) - mask |= S_IRUSR; - if (acc_mode & PUFFS_VWRITE) - mask |= S_IWUSR; - /* group */ - } else if (puffs_cred_hasgroup(pcr, gid)) { - if (acc_mode & PUFFS_VEXEC) - mask |= S_IXGRP; - if (acc_mode & PUFFS_VREAD) - mask |= S_IRGRP; - if (acc_mode & PUFFS_VWRITE) - mask |= S_IWGRP; - /* other */ - } else { - if (acc_mode & PUFFS_VEXEC) - mask |= S_IXOTH; - if (acc_mode & PUFFS_VREAD) - mask |= S_IROTH; - if (acc_mode & PUFFS_VWRITE) - mask |= S_IWOTH; - } - - if ((file_mode & mask) == mask) - return 0; - else - return EACCES; -} - -int -puffs_access_chown(uid_t owner, gid_t group, uid_t newowner, gid_t newgroup, - const struct puffs_cred *pcr) -{ - - if (newowner == (uid_t)PUFFS_VNOVAL) - newowner = owner; - if (newgroup == (gid_t)PUFFS_VNOVAL) - newgroup = group; - - if ((!puffs_cred_isuid(pcr, owner) || newowner != owner || - ((newgroup != group && !puffs_cred_hasgroup(pcr, newgroup)))) - && !puffs_cred_isjuggernaut(pcr)) - return EPERM; - - return 0; -} - -int -puffs_access_chmod(uid_t owner, gid_t group, enum vtype type, mode_t mode, - const struct puffs_cred *pcr) -{ - - if (!puffs_cred_isuid(pcr, owner) && !puffs_cred_isjuggernaut(pcr)) - return EPERM; - - if (!puffs_cred_isjuggernaut(pcr)) { - if (type != VDIR && (mode & S_ISTXT)) - return EFTYPE; - if (!puffs_cred_hasgroup(pcr, group) && (mode & S_ISGID)) - return EPERM; - } - - return 0; -} - -int -puffs_access_times(uid_t uid, gid_t gid, mode_t mode, int va_utimes_null, - const struct puffs_cred *pcr) -{ - - if (puffs_cred_isuid(pcr, uid) || puffs_cred_isjuggernaut(pcr)) - return 0; - - if (va_utimes_null == 0) - return EPERM; - - return puffs_access(VNON, mode, uid, gid, PUFFS_VWRITE, pcr); -} diff --git a/lib/libpuffs/dispatcher.c b/lib/libpuffs/dispatcher.c deleted file mode 100644 index 79cc28de5..000000000 --- a/lib/libpuffs/dispatcher.c +++ /dev/null @@ -1,1209 +0,0 @@ -/* $NetBSD: dispatcher.c,v 1.48 2014/10/31 13:56:04 manu Exp $ */ - -/* - * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Ulla Tuominen Foundation, the Finnish Cultural Foundation and - * Research Foundation of Helsinki University of Technology. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: dispatcher.c,v 1.48 2014/10/31 13:56:04 manu Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -#define PUFFS_USE_FS_TTL(pu) (pu->pu_flags & PUFFS_KFLAG_CACHE_FS_TTL) - -static void dispatch(struct puffs_cc *); - -/* for our eyes only */ -void -puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb) -{ - struct puffs_cc *pcc = puffs_cc_getcc(pu); - struct puffs_req *preq; - - pcc->pcc_pb = pb; - pcc->pcc_flags |= PCC_MLCONT; - dispatch(pcc); - - /* Put result to kernel sendqueue if necessary */ - preq = puffs__framebuf_getdataptr(pcc->pcc_pb); - if (PUFFSOP_WANTREPLY(preq->preq_opclass)) { - if (pu->pu_flags & PUFFS_FLAG_OPDUMP) - puffsdump_rv(preq); - - puffs_framev_enqueue_justsend(pu, pu->pu_fd, - pcc->pcc_pb, 0, 0); - } else { - puffs_framebuf_destroy(pcc->pcc_pb); - } - - /* who needs information when you're living on borrowed time? */ - if (pcc->pcc_flags & PCC_BORROWED) { - puffs_cc_yield(pcc); /* back to borrow source */ - } - pcc->pcc_flags = 0; -} - -/* public, but not really tested and only semi-supported */ -int -puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb, - struct puffs_cc **pccp) -{ - struct puffs_cc *pcc; - - if (puffs__cc_create(pu, dispatch, &pcc) == -1) - return -1; - - pcc->pcc_pb = pb; - *pccp = pcc; - - return 0; -} - -int -puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp) -{ - int rv; - - puffs_cc_continue(pcc); - - if (pcc->pcc_flags & PCC_DONE) { - rv = 1; - *pbp = pcc->pcc_pb; - pcc->pcc_flags = 0; - puffs__cc_destroy(pcc, 0); - } else { - rv = 0; - } - - return rv; -} - -static void -dispatch(struct puffs_cc *pcc) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - struct puffs_ops *pops = &pu->pu_ops; - struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb); - void *auxbuf; /* help with typecasting */ - puffs_cookie_t opcookie; - int error = 0, buildpath, pncookie; - - /* XXX: smaller hammer, please */ - if ((PUFFSOP_OPCLASS(preq->preq_opclass == PUFFSOP_VFS && - preq->preq_optype == PUFFS_VFS_VPTOFH)) || - (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN && - (preq->preq_optype == PUFFS_VN_READDIR - || preq->preq_optype == PUFFS_VN_READ))) { - if (puffs_framebuf_reserve_space(pcc->pcc_pb, - PUFFS_MSG_MAXSIZE) == -1) - error = errno; - preq = puffs__framebuf_getdataptr(pcc->pcc_pb); - } - - auxbuf = preq; - opcookie = preq->preq_cookie; - - assert((pcc->pcc_flags & PCC_DONE) == 0); - - buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH; - pncookie = pu->pu_flags & PUFFS_FLAG_PNCOOKIE; - assert(!buildpath || pncookie); - - preq->preq_setbacks = 0; - - if (pu->pu_flags & PUFFS_FLAG_OPDUMP) - puffsdump_req(preq); - - puffs__cc_setcaller(pcc, preq->preq_pid, preq->preq_lid); - - /* pre-operation */ - if (pu->pu_oppre) - pu->pu_oppre(pu); - - if (error) - goto out; - - /* Execute actual operation */ - if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) { - switch (preq->preq_optype) { - case PUFFS_VFS_UNMOUNT: - { - struct puffs_vfsmsg_unmount *auxt = auxbuf; - - PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTING); - error = pops->puffs_fs_unmount(pu, auxt->pvfsr_flags); - if (!error) - PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED); - else - PU_SETSTATE(pu, PUFFS_STATE_RUNNING); - break; - } - - case PUFFS_VFS_STATVFS: - { - struct puffs_vfsmsg_statvfs *auxt = auxbuf; - - error = pops->puffs_fs_statvfs(pu, &auxt->pvfsr_sb); - break; - } - - case PUFFS_VFS_SYNC: - { - struct puffs_vfsmsg_sync *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvfsr_cred); - - error = pops->puffs_fs_sync(pu, - auxt->pvfsr_waitfor, pcr); - break; - } - - case PUFFS_VFS_FHTOVP: - { - struct puffs_vfsmsg_fhtonode *auxt = auxbuf; - struct puffs_newinfo pni; - - pni.pni_cookie = &auxt->pvfsr_fhcookie; - pni.pni_vtype = &auxt->pvfsr_vtype; - pni.pni_size = &auxt->pvfsr_size; - pni.pni_rdev = &auxt->pvfsr_rdev; - pni.pni_va = NULL; - pni.pni_va_ttl = NULL; - pni.pni_cn_ttl = NULL; - - error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data, - auxt->pvfsr_dsize, &pni); - - break; - } - - case PUFFS_VFS_VPTOFH: - { - struct puffs_vfsmsg_nodetofh *auxt = auxbuf; - - error = pops->puffs_fs_nodetofh(pu, - auxt->pvfsr_fhcookie, auxt->pvfsr_data, - &auxt->pvfsr_dsize); - - break; - } - - case PUFFS_VFS_EXTATTRCTL: - { - struct puffs_vfsmsg_extattrctl *auxt = auxbuf; - const char *attrname; - int flags; - - if (pops->puffs_fs_extattrctl == NULL) { - error = EOPNOTSUPP; - break; - } - - if (auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASATTRNAME) - attrname = auxt->pvfsr_attrname; - else - attrname = NULL; - - flags = auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASNODE; - error = pops->puffs_fs_extattrctl(pu, auxt->pvfsr_cmd, - opcookie, flags, - auxt->pvfsr_attrnamespace, attrname); - break; - } - - default: - /* - * I guess the kernel sees this one coming - */ - error = EINVAL; - break; - } - - /* XXX: audit return values */ - /* XXX: sync with kernel */ - } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { - switch (preq->preq_optype) { - case PUFFS_VN_LOOKUP: - { - struct puffs_vnmsg_lookup *auxt = auxbuf; - struct puffs_newinfo pni; - struct puffs_cn pcn; - struct puffs_node *pn = NULL; - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - pni.pni_cookie = &auxt->pvnr_newnode; - pni.pni_vtype = &auxt->pvnr_vtype; - pni.pni_size = &auxt->pvnr_size; - pni.pni_rdev = &auxt->pvnr_rdev; - pni.pni_va = &auxt->pvnr_va; - pni.pni_va_ttl = &auxt->pvnr_va_ttl; - pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; - - if (buildpath) { - error = puffs_path_pcnbuild(pu, &pcn, opcookie); - if (error) - break; - } - - /* lookup *must* be present */ - error = pops->puffs_node_lookup(pu, opcookie, - &pni, &pcn); - - if (buildpath) { - if (error) { - pu->pu_pathfree(pu, &pcn.pcn_po_full); - } else { - /* - * did we get a new node or a - * recycled node? - */ - pn = PU_CMAP(pu, auxt->pvnr_newnode); - if (pn->pn_po.po_path == NULL) - pn->pn_po = pcn.pcn_po_full; - else - pu->pu_pathfree(pu, - &pcn.pcn_po_full); - } - } - - if (pncookie && !error) { - if (pn == NULL) - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_nlookup++; - } - break; - } - - case PUFFS_VN_CREATE: - { - struct puffs_vnmsg_create *auxt = auxbuf; - struct puffs_newinfo pni; - struct puffs_cn pcn; - struct puffs_node *pn = NULL; - - if (pops->puffs_node_create == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - memset(&pni, 0, sizeof(pni)); - pni.pni_cookie = &auxt->pvnr_newnode; - pni.pni_va = &auxt->pvnr_va; - pni.pni_va_ttl = &auxt->pvnr_va_ttl; - pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; - - if (buildpath) { - error = puffs_path_pcnbuild(pu, &pcn, opcookie); - if (error) - break; - } - - error = pops->puffs_node_create(pu, - opcookie, &pni, &pcn, &auxt->pvnr_va); - - if (buildpath) { - if (error) { - pu->pu_pathfree(pu, &pcn.pcn_po_full); - } else { - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_po = pcn.pcn_po_full; - } - } - - if (pncookie && !error) { - if (pn == NULL) - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_nlookup++; - } - break; - } - - case PUFFS_VN_MKNOD: - { - struct puffs_vnmsg_mknod *auxt = auxbuf; - struct puffs_newinfo pni; - struct puffs_cn pcn; - struct puffs_node *pn = NULL; - - if (pops->puffs_node_mknod == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - memset(&pni, 0, sizeof(pni)); - pni.pni_cookie = &auxt->pvnr_newnode; - pni.pni_va = &auxt->pvnr_va; - pni.pni_va_ttl = &auxt->pvnr_va_ttl; - pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; - - if (buildpath) { - error = puffs_path_pcnbuild(pu, &pcn, opcookie); - if (error) - break; - } - - error = pops->puffs_node_mknod(pu, - opcookie, &pni, &pcn, &auxt->pvnr_va); - - if (buildpath) { - if (error) { - pu->pu_pathfree(pu, &pcn.pcn_po_full); - } else { - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_po = pcn.pcn_po_full; - } - } - - if (pncookie && !error) { - if (pn == NULL) - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_nlookup++; - } - break; - } - - case PUFFS_VN_OPEN: - { - struct puffs_vnmsg_open *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_open2 != NULL) { - error = pops->puffs_node_open2(pu, - opcookie, auxt->pvnr_mode, pcr, - &auxt->pvnr_oflags); - - break; - } - - if (pops->puffs_node_open == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_open(pu, - opcookie, auxt->pvnr_mode, pcr); - break; - } - - case PUFFS_VN_CLOSE: - { - struct puffs_vnmsg_close *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_close == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_close(pu, - opcookie, auxt->pvnr_fflag, pcr); - break; - } - - case PUFFS_VN_ACCESS: - { - struct puffs_vnmsg_access *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_access == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_access(pu, - opcookie, auxt->pvnr_mode, pcr); - break; - } - - case PUFFS_VN_GETATTR: - { - struct puffs_vnmsg_getattr *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (PUFFS_USE_FS_TTL(pu)) { - if (pops->puffs_node_getattr_ttl == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_getattr_ttl(pu, - opcookie, &auxt->pvnr_va, pcr, - &auxt->pvnr_va_ttl); - } else { - if (pops->puffs_node_getattr == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_getattr(pu, - opcookie, &auxt->pvnr_va, pcr); - } - break; - } - - case PUFFS_VN_SETATTR: - { - struct puffs_vnmsg_setattr *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (PUFFS_USE_FS_TTL(pu)) { - int xflag = 0; - - if (pops->puffs_node_setattr_ttl == NULL) { - error = EOPNOTSUPP; - break; - } - - if (!PUFFSOP_WANTREPLY(preq->preq_opclass)) - xflag |= PUFFS_SETATTR_FAF; - - error = pops->puffs_node_setattr_ttl(pu, - opcookie, &auxt->pvnr_va, pcr, - &auxt->pvnr_va_ttl, xflag); - } else { - if (pops->puffs_node_setattr == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_setattr(pu, - opcookie, &auxt->pvnr_va, pcr); - } - break; - } - - case PUFFS_VN_MMAP: - { - struct puffs_vnmsg_mmap *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_mmap == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_mmap(pu, - opcookie, auxt->pvnr_prot, pcr); - break; - } - - case PUFFS_VN_FSYNC: - { - struct puffs_vnmsg_fsync *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_fsync == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_fsync(pu, opcookie, pcr, - auxt->pvnr_flags, auxt->pvnr_offlo, - auxt->pvnr_offhi); - break; - } - - case PUFFS_VN_SEEK: - { - struct puffs_vnmsg_seek *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_seek == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_seek(pu, - opcookie, auxt->pvnr_oldoff, - auxt->pvnr_newoff, pcr); - break; - } - - case PUFFS_VN_REMOVE: - { - struct puffs_vnmsg_remove *auxt = auxbuf; - struct puffs_cn pcn; - if (pops->puffs_node_remove == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - error = pops->puffs_node_remove(pu, - opcookie, auxt->pvnr_cookie_targ, &pcn); - break; - } - - case PUFFS_VN_LINK: - { - struct puffs_vnmsg_link *auxt = auxbuf; - struct puffs_cn pcn; - if (pops->puffs_node_link == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - if (buildpath) { - error = puffs_path_pcnbuild(pu, &pcn, opcookie); - if (error) - break; - } - - error = pops->puffs_node_link(pu, - opcookie, auxt->pvnr_cookie_targ, &pcn); - if (buildpath) - pu->pu_pathfree(pu, &pcn.pcn_po_full); - - break; - } - - case PUFFS_VN_RENAME: - { - struct puffs_vnmsg_rename *auxt = auxbuf; - struct puffs_cn pcn_src, pcn_targ; - struct puffs_node *pn_src; - - if (pops->puffs_node_rename == NULL) { - error = 0; - break; - } - - pcn_src.pcn_pkcnp = &auxt->pvnr_cn_src; - PUFFS_KCREDTOCRED(pcn_src.pcn_cred, - &auxt->pvnr_cn_src_cred); - - pcn_targ.pcn_pkcnp = &auxt->pvnr_cn_targ; - PUFFS_KCREDTOCRED(pcn_targ.pcn_cred, - &auxt->pvnr_cn_targ_cred); - - if (buildpath) { - pn_src = auxt->pvnr_cookie_src; - pcn_src.pcn_po_full = pn_src->pn_po; - - error = puffs_path_pcnbuild(pu, &pcn_targ, - auxt->pvnr_cookie_targdir); - if (error) - break; - } - - error = pops->puffs_node_rename(pu, - opcookie, auxt->pvnr_cookie_src, - &pcn_src, auxt->pvnr_cookie_targdir, - auxt->pvnr_cookie_targ, &pcn_targ); - - if (buildpath) { - if (error) { - pu->pu_pathfree(pu, - &pcn_targ.pcn_po_full); - } else { - struct puffs_pathinfo pi; - struct puffs_pathobj po_old; - - /* handle this node */ - po_old = pn_src->pn_po; - pn_src->pn_po = pcn_targ.pcn_po_full; - - if (pn_src->pn_va.va_type != VDIR) { - pu->pu_pathfree(pu, &po_old); - break; - } - - /* handle all child nodes for DIRs */ - pi.pi_old = &pcn_src.pcn_po_full; - pi.pi_new = &pcn_targ.pcn_po_full; - - PU_LOCK(); - if (puffs_pn_nodewalk(pu, - puffs_path_prefixadj, &pi) != NULL) - error = ENOMEM; - PU_UNLOCK(); - pu->pu_pathfree(pu, &po_old); - } - } - break; - } - - case PUFFS_VN_MKDIR: - { - struct puffs_vnmsg_mkdir *auxt = auxbuf; - struct puffs_newinfo pni; - struct puffs_cn pcn; - struct puffs_node *pn = NULL; - - if (pops->puffs_node_mkdir == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - memset(&pni, 0, sizeof(pni)); - pni.pni_cookie = &auxt->pvnr_newnode; - pni.pni_va = &auxt->pvnr_va; - pni.pni_va_ttl = &auxt->pvnr_va_ttl; - pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; - - if (buildpath) { - error = puffs_path_pcnbuild(pu, &pcn, opcookie); - if (error) - break; - } - - error = pops->puffs_node_mkdir(pu, - opcookie, &pni, &pcn, &auxt->pvnr_va); - - if (buildpath) { - if (error) { - pu->pu_pathfree(pu, &pcn.pcn_po_full); - } else { - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_po = pcn.pcn_po_full; - } - } - - if (pncookie && !error) { - if (pn == NULL) - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_nlookup++; - } - break; - } - - case PUFFS_VN_RMDIR: - { - struct puffs_vnmsg_rmdir *auxt = auxbuf; - struct puffs_cn pcn; - if (pops->puffs_node_rmdir == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - error = pops->puffs_node_rmdir(pu, - opcookie, auxt->pvnr_cookie_targ, &pcn); - break; - } - - case PUFFS_VN_SYMLINK: - { - struct puffs_vnmsg_symlink *auxt = auxbuf; - struct puffs_newinfo pni; - struct puffs_cn pcn; - struct puffs_node *pn = NULL; - - if (pops->puffs_node_symlink == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - memset(&pni, 0, sizeof(pni)); - pni.pni_cookie = &auxt->pvnr_newnode; - pni.pni_va = &auxt->pvnr_va; - pni.pni_va_ttl = &auxt->pvnr_va_ttl; - pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; - - if (buildpath) { - error = puffs_path_pcnbuild(pu, &pcn, opcookie); - if (error) - break; - } - - error = pops->puffs_node_symlink(pu, - opcookie, &pni, &pcn, - &auxt->pvnr_va, auxt->pvnr_link); - - if (buildpath) { - if (error) { - pu->pu_pathfree(pu, &pcn.pcn_po_full); - } else { - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_po = pcn.pcn_po_full; - } - } - - if (pncookie && !error) { - if (pn == NULL) - pn = PU_CMAP(pu, auxt->pvnr_newnode); - pn->pn_nlookup++; - } - break; - } - - case PUFFS_VN_READDIR: - { - struct puffs_vnmsg_readdir *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - struct dirent *dent; - off_t *cookies; - size_t res, origcookies; - - if (pops->puffs_node_readdir == NULL) { - error = 0; - break; - } - - if (auxt->pvnr_ncookies) { - /* LINTED: pvnr_data is __aligned() */ - cookies = (off_t *)auxt->pvnr_data; - origcookies = auxt->pvnr_ncookies; - } else { - cookies = NULL; - origcookies = 0; - } - /* LINTED: dentoff is aligned in the kernel */ - dent = (struct dirent *) - (auxt->pvnr_data + auxt->pvnr_dentoff); - - res = auxt->pvnr_resid; - error = pops->puffs_node_readdir(pu, - opcookie, dent, &auxt->pvnr_offset, - &auxt->pvnr_resid, pcr, &auxt->pvnr_eofflag, - cookies, &auxt->pvnr_ncookies); - - /* much easier to track non-working NFS */ - assert(auxt->pvnr_ncookies <= origcookies); - - /* need to move a bit more */ - preq->preq_buflen = sizeof(struct puffs_vnmsg_readdir) - + auxt->pvnr_dentoff + (res - auxt->pvnr_resid); - break; - } - - case PUFFS_VN_READLINK: - { - struct puffs_vnmsg_readlink *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_readlink == NULL) { - error = EOPNOTSUPP; - break; - } - - /*LINTED*/ - error = pops->puffs_node_readlink(pu, opcookie, pcr, - auxt->pvnr_link, &auxt->pvnr_linklen); - break; - } - - case PUFFS_VN_RECLAIM: - { - struct puffs_vnmsg_reclaim *auxt = auxbuf; - struct puffs_node *pn; - - if (pops->puffs_node_reclaim2 != NULL) { - error = pops->puffs_node_reclaim2(pu, opcookie, - auxt->pvnr_nlookup); - break; - } - - if (pops->puffs_node_reclaim == NULL) { - error = 0; - break; - } - - /* - * This fixes a race condition, - * where a node in reclaimed by kernel - * after a lookup request is sent, - * but before the reply, leaving the kernel - * with a invalid vnode/cookie reference. - */ - if (pncookie) { - pn = PU_CMAP(pu, opcookie); - pn->pn_nlookup -= auxt->pvnr_nlookup; - if (pn->pn_nlookup >= 1) { - error = 0; - break; - } - } - - error = pops->puffs_node_reclaim(pu, opcookie); - break; - } - - case PUFFS_VN_INACTIVE: - { - - if (pops->puffs_node_inactive == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_inactive(pu, opcookie); - break; - } - - case PUFFS_VN_PATHCONF: - { - struct puffs_vnmsg_pathconf *auxt = auxbuf; - if (pops->puffs_node_pathconf == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_pathconf(pu, - opcookie, auxt->pvnr_name, - &auxt->pvnr_retval); - break; - } - - case PUFFS_VN_ADVLOCK: - { - struct puffs_vnmsg_advlock *auxt = auxbuf; - if (pops->puffs_node_advlock == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_advlock(pu, - opcookie, auxt->pvnr_id, auxt->pvnr_op, - &auxt->pvnr_fl, auxt->pvnr_flags); - break; - } - - case PUFFS_VN_PRINT: - { - if (pops->puffs_node_print == NULL) { - error = 0; - break; - } - - error = pops->puffs_node_print(pu, - opcookie); - break; - } - - case PUFFS_VN_ABORTOP: - { - struct puffs_vnmsg_abortop *auxt = auxbuf; - struct puffs_cn pcn; - - if (pops->puffs_node_abortop == NULL) { - error = 0; - break; - } - - pcn.pcn_pkcnp = &auxt->pvnr_cn; - PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); - - error = pops->puffs_node_abortop(pu, opcookie, &pcn); - - break; - } - - case PUFFS_VN_READ: - { - struct puffs_vnmsg_read *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - size_t res; - - if (pops->puffs_node_read == NULL) { - error = EIO; - break; - } - - res = auxt->pvnr_resid; - error = pops->puffs_node_read(pu, - opcookie, auxt->pvnr_data, - auxt->pvnr_offset, &auxt->pvnr_resid, - pcr, auxt->pvnr_ioflag); - - /* need to move a bit more */ - preq->preq_buflen = sizeof(struct puffs_vnmsg_read) - + (res - auxt->pvnr_resid); - break; - } - - case PUFFS_VN_WRITE: - { - struct puffs_vnmsg_write *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_write2 != NULL) { - int xflag = 0; - - if (!PUFFSOP_WANTREPLY(preq->preq_opclass)) - xflag |= PUFFS_SETATTR_FAF; - - error = pops->puffs_node_write2(pu, - opcookie, auxt->pvnr_data, - auxt->pvnr_offset, &auxt->pvnr_resid, - pcr, auxt->pvnr_ioflag, xflag); - - } else if (pops->puffs_node_write != NULL) { - error = pops->puffs_node_write(pu, - opcookie, auxt->pvnr_data, - auxt->pvnr_offset, &auxt->pvnr_resid, - pcr, auxt->pvnr_ioflag); - } else { - error = EIO; - break; - } - - - /* don't need to move data back to the kernel */ - preq->preq_buflen = sizeof(struct puffs_vnmsg_write); - break; - } - - case PUFFS_VN_POLL: - { - struct puffs_vnmsg_poll *auxt = auxbuf; - - if (pops->puffs_node_poll == NULL) { - error = 0; - - /* emulate genfs_poll() */ - auxt->pvnr_events &= (POLLIN | POLLOUT - | POLLRDNORM | POLLWRNORM); - - break; - } - - error = pops->puffs_node_poll(pu, - opcookie, &auxt->pvnr_events); - break; - } - - case PUFFS_VN_GETEXTATTR: - { - struct puffs_vnmsg_getextattr *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - size_t res, *resp, *sizep; - uint8_t *data; - - if (pops->puffs_node_getextattr == NULL) { - error = EOPNOTSUPP; - break; - } - - if (auxt->pvnr_datasize) - sizep = &auxt->pvnr_datasize; - else - sizep = NULL; - - res = auxt->pvnr_resid; - if (res > 0) { - data = auxt->pvnr_data; - resp = &auxt->pvnr_resid; - } else { - data = NULL; - resp = NULL; - } - - error = pops->puffs_node_getextattr(pu, - opcookie, auxt->pvnr_attrnamespace, - auxt->pvnr_attrname, sizep, data, resp, pcr); - - /* need to move a bit more? */ - preq->preq_buflen = - sizeof(struct puffs_vnmsg_getextattr) - + (res - auxt->pvnr_resid); - break; - } - - case PUFFS_VN_SETEXTATTR: - { - struct puffs_vnmsg_setextattr *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - size_t *resp; - uint8_t *data; - - if (pops->puffs_node_setextattr == NULL) { - error = EOPNOTSUPP; - break; - } - - if (auxt->pvnr_resid > 0) { - data = auxt->pvnr_data; - resp = &auxt->pvnr_resid; - } else { - data = NULL; - resp = NULL; - } - - error = pops->puffs_node_setextattr(pu, - opcookie, auxt->pvnr_attrnamespace, - auxt->pvnr_attrname, data, resp, pcr); - break; - } - - case PUFFS_VN_LISTEXTATTR: - { - struct puffs_vnmsg_listextattr *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - size_t res, *resp, *sizep; - int flag; - uint8_t *data; - - if (pops->puffs_node_listextattr == NULL) { - error = EOPNOTSUPP; - break; - } - - if (auxt->pvnr_datasize) - sizep = &auxt->pvnr_datasize; - else - sizep = NULL; - - res = auxt->pvnr_resid; - if (res > 0) { - data = auxt->pvnr_data; - resp = &auxt->pvnr_resid; - } else { - data = NULL; - resp = NULL; - } - - res = auxt->pvnr_resid; - flag = auxt->pvnr_flag; - error = pops->puffs_node_listextattr(pu, - opcookie, auxt->pvnr_attrnamespace, - sizep, data, resp, flag, pcr); - - /* need to move a bit more? */ - preq->preq_buflen = - sizeof(struct puffs_vnmsg_listextattr) - + (res - auxt->pvnr_resid); - break; - } - - case PUFFS_VN_DELETEEXTATTR: - { - struct puffs_vnmsg_deleteextattr *auxt = auxbuf; - PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); - - if (pops->puffs_node_deleteextattr == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_deleteextattr(pu, - opcookie, auxt->pvnr_attrnamespace, - auxt->pvnr_attrname, pcr); - break; - } - - case PUFFS_VN_FALLOCATE: - { - struct puffs_vnmsg_fallocate *auxt = auxbuf; - - if (pops->puffs_node_fallocate == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_fallocate(pu, - opcookie, auxt->pvnr_off, auxt->pvnr_len); - break; - } - - case PUFFS_VN_FDISCARD: - { - struct puffs_vnmsg_fdiscard *auxt = auxbuf; - - if (pops->puffs_node_fdiscard == NULL) { - error = EOPNOTSUPP; - break; - } - - error = pops->puffs_node_fdiscard(pu, - opcookie, auxt->pvnr_off, auxt->pvnr_len); - break; - } - - default: - printf("inval op %d\n", preq->preq_optype); - error = EINVAL; - break; - } - -#if 0 - /* not issued by kernel currently */ - } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_CACHE) { - struct puffs_cacheinfo *pci = (void *)preq; - - if (pu->pu_ops.puffs_cache_write) { - pu->pu_ops.puffs_cache_write(pu, preq->preq_cookie, - pci->pcache_nruns, pci->pcache_runs); - } - error = 0; -#endif - - } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_ERROR) { - struct puffs_error *perr = (void *)preq; - - pu->pu_errnotify(pu, preq->preq_optype, - perr->perr_error, perr->perr_str, preq->preq_cookie); - error = 0; - } else { - /* - * I guess the kernel sees this one coming also - */ - error = EINVAL; - } - - out: - preq->preq_rv = error; - - if (pu->pu_oppost) - pu->pu_oppost(pu); - - pcc->pcc_flags |= PCC_DONE; -} diff --git a/lib/libpuffs/flush.c b/lib/libpuffs/flush.c deleted file mode 100644 index 51d3db32f..000000000 --- a/lib/libpuffs/flush.c +++ /dev/null @@ -1,135 +0,0 @@ -/* $NetBSD: flush.c,v 1.16 2008/08/12 19:44:39 pooka Exp $ */ - -/* - * Copyright (c) 2007 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: flush.c,v 1.16 2008/08/12 19:44:39 pooka Exp $"); -#endif /* !lint */ - -/* - * Flushing / invalidation routines - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -#if 0 -int -puffs_inval_namecache_node(struct puffs_usermount *pu, puffs_cookie_t cookie, - const char *name) -{ - - return EOPNOTSUPP; -} -#endif - -static int -doflush(struct puffs_usermount *pu, puffs_cookie_t cookie, int op, - off_t start, off_t end) -{ - struct puffs_framebuf *pb; - struct puffs_flush *pf; - size_t winlen; - int rv; - - pb = puffs_framebuf_make(); - if (pb == NULL) - return ENOMEM; - - winlen = sizeof(struct puffs_flush); - if ((rv = puffs_framebuf_getwindow(pb, 0, (void *)&pf, &winlen)) == -1) - goto out; - assert(winlen == sizeof(struct puffs_flush)); - - pf->pf_req.preq_buflen = sizeof(struct puffs_flush); - pf->pf_req.preq_opclass = PUFFSOP_FLUSH; - pf->pf_req.preq_id = puffs__nextreq(pu); - - pf->pf_op = op; - pf->pf_cookie = cookie; - pf->pf_start = start; - pf->pf_end = end; - - rv = puffs_framev_enqueue_cc(puffs_cc_getcc(pu), - puffs_getselectable(pu), pb, 0); - - out: - puffs_framebuf_destroy(pb); - return rv; -} - -int -puffs_inval_namecache_dir(struct puffs_usermount *pu, puffs_cookie_t cookie) -{ - - return doflush(pu, cookie, PUFFS_INVAL_NAMECACHE_DIR, 0, 0); -} - -int -puffs_inval_namecache_all(struct puffs_usermount *pu) -{ - - return doflush(pu, NULL, PUFFS_INVAL_NAMECACHE_ALL, 0, 0); -} - -int -puffs_inval_pagecache_node(struct puffs_usermount *pu, puffs_cookie_t cookie) -{ - - return doflush(pu, cookie, PUFFS_INVAL_PAGECACHE_NODE_RANGE, 0, 0); -} - -int -puffs_inval_pagecache_node_range(struct puffs_usermount *pu, - puffs_cookie_t cookie, off_t start, off_t end) -{ - - return doflush(pu, cookie, PUFFS_INVAL_PAGECACHE_NODE_RANGE, start,end); -} - -int -puffs_flush_pagecache_node(struct puffs_usermount *pu, puffs_cookie_t cookie) -{ - - return doflush(pu, cookie, PUFFS_FLUSH_PAGECACHE_NODE_RANGE, 0, 0); -} - -int -puffs_flush_pagecache_node_range(struct puffs_usermount *pu, - puffs_cookie_t cookie, off_t start, off_t end) -{ - - return doflush(pu, cookie, PUFFS_FLUSH_PAGECACHE_NODE_RANGE, start,end); -} diff --git a/lib/libpuffs/framebuf.c b/lib/libpuffs/framebuf.c deleted file mode 100644 index b76cd64a9..000000000 --- a/lib/libpuffs/framebuf.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* $NetBSD: framebuf.c,v 1.32 2012/06/25 22:32:47 abs Exp $ */ - -/* - * Copyright (c) 2007 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Finnish Cultural Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * The event portion of this code is a twisty maze of pointers, - * flags, yields and continues. Sincere aplogies. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: framebuf.c,v 1.32 2012/06/25 22:32:47 abs Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -struct puffs_framebuf { - struct puffs_cc *pcc; /* pcc to continue with */ - /* OR */ - puffs_framev_cb fcb; /* non-blocking callback */ - void *fcb_arg; /* argument for previous */ - - uint8_t *buf; /* buffer base */ - size_t len; /* total length */ - - size_t offset; /* cursor, telloff() */ - size_t maxoff; /* maximum offset for data, tellsize() */ - - volatile int rv; /* errno value */ - - int istat; - - TAILQ_ENTRY(puffs_framebuf) pfb_entries; -}; -#define ISTAT_NODESTROY 0x01 /* indestructible by framebuf_destroy() */ -#define ISTAT_INTERNAL 0x02 /* never leaves library */ -#define ISTAT_NOREPLY 0x04 /* nuke after sending */ -#define ISTAT_DIRECT 0x08 /* receive directly, no moveinfo */ - -#define ISTAT_ONQUEUE ISTAT_NODESTROY /* alias */ - -#define PUFBUF_INCRALLOC 4096 -#define PUFBUF_REMAIN(p) (p->len - p->offset) - -/* for poll/kqueue */ -struct puffs_fbevent { - struct puffs_cc *pcc; - int what; - volatile int rv; - - LIST_ENTRY(puffs_fbevent) pfe_entries; -}; - -static struct puffs_fctrl_io * -getfiobyfd(struct puffs_usermount *pu, int fd) -{ - struct puffs_fctrl_io *fio; - - LIST_FOREACH(fio, &pu->pu_ios, fio_entries) - if (fio->io_fd == fd) - return fio; - return NULL; -} - -struct puffs_framebuf * -puffs_framebuf_make(void) -{ - struct puffs_framebuf *pufbuf; - - pufbuf = malloc(sizeof(struct puffs_framebuf)); - if (pufbuf == NULL) - return NULL; - memset(pufbuf, 0, sizeof(struct puffs_framebuf)); - - pufbuf->buf = malloc(PUFBUF_INCRALLOC); - if (pufbuf->buf == NULL) { - free(pufbuf); - return NULL; - } - pufbuf->len = PUFBUF_INCRALLOC; - - puffs_framebuf_recycle(pufbuf); - return pufbuf; -} - -void -puffs_framebuf_destroy(struct puffs_framebuf *pufbuf) -{ - - assert((pufbuf->istat & ISTAT_NODESTROY) == 0); - - free(pufbuf->buf); - free(pufbuf); -} - -void -puffs_framebuf_recycle(struct puffs_framebuf *pufbuf) -{ - - assert((pufbuf->istat & ISTAT_NODESTROY) == 0); - - pufbuf->offset = 0; - pufbuf->maxoff = 0; - pufbuf->istat = 0; -} - -static int -reservespace(struct puffs_framebuf *pufbuf, size_t off, size_t wantsize) -{ - size_t incr; - void *nd; - - if (off <= pufbuf->len && pufbuf->len - off >= wantsize) - return 0; - - for (incr = PUFBUF_INCRALLOC; - pufbuf->len + incr < off + wantsize; - incr += PUFBUF_INCRALLOC) - continue; - - nd = realloc(pufbuf->buf, pufbuf->len + incr); - if (nd == NULL) - return -1; - - pufbuf->buf = nd; - pufbuf->len += incr; - - return 0; -} - -int -puffs_framebuf_dup(struct puffs_framebuf *pb, struct puffs_framebuf **pbp) -{ - struct puffs_framebuf *newpb; - - newpb = puffs_framebuf_make(); - if (newpb == NULL) { - errno = ENOMEM; - return -1; - } - memcpy(newpb, pb, sizeof(struct puffs_framebuf)); - - newpb->buf = NULL; - newpb->len = 0; - if (reservespace(newpb, 0, pb->maxoff) == -1) { - puffs_framebuf_destroy(newpb); - return -1; - } - - memcpy(newpb->buf, pb->buf, pb->maxoff); - newpb->istat = 0; - *pbp = newpb; - - return 0; -} - -int -puffs_framebuf_reserve_space(struct puffs_framebuf *pufbuf, size_t wantsize) -{ - - return reservespace(pufbuf, pufbuf->offset, wantsize); -} - -int -puffs_framebuf_putdata(struct puffs_framebuf *pufbuf, - const void *data, size_t dlen) -{ - - if (PUFBUF_REMAIN(pufbuf) < dlen) - if (puffs_framebuf_reserve_space(pufbuf, dlen) == -1) - return -1; - - memcpy(pufbuf->buf + pufbuf->offset, data, dlen); - pufbuf->offset += dlen; - - if (pufbuf->offset > pufbuf->maxoff) - pufbuf->maxoff = pufbuf->offset; - - return 0; -} - -int -puffs_framebuf_putdata_atoff(struct puffs_framebuf *pufbuf, size_t offset, - const void *data, size_t dlen) -{ - - if (reservespace(pufbuf, offset, dlen) == -1) - return -1; - - memcpy(pufbuf->buf + offset, data, dlen); - - if (offset + dlen > pufbuf->maxoff) - pufbuf->maxoff = offset + dlen; - - return 0; -} - -int -puffs_framebuf_getdata(struct puffs_framebuf *pufbuf, void *data, size_t dlen) -{ - - if (pufbuf->maxoff < pufbuf->offset + dlen) { - errno = ENOBUFS; - return -1; - } - - memcpy(data, pufbuf->buf + pufbuf->offset, dlen); - pufbuf->offset += dlen; - - return 0; -} - -int -puffs_framebuf_getdata_atoff(struct puffs_framebuf *pufbuf, size_t offset, - void *data, size_t dlen) -{ - - if (pufbuf->maxoff < offset + dlen) { - errno = ENOBUFS; - return -1; - } - - memcpy(data, pufbuf->buf + offset, dlen); - return 0; -} - -size_t -puffs_framebuf_telloff(struct puffs_framebuf *pufbuf) -{ - - return pufbuf->offset; -} - -size_t -puffs_framebuf_tellsize(struct puffs_framebuf *pufbuf) -{ - - return pufbuf->maxoff; -} - -size_t -puffs_framebuf_remaining(struct puffs_framebuf *pufbuf) -{ - - return puffs_framebuf_tellsize(pufbuf) - puffs_framebuf_telloff(pufbuf); -} - -int -puffs_framebuf_seekset(struct puffs_framebuf *pufbuf, size_t newoff) -{ - - if (reservespace(pufbuf, newoff, 0) == -1) - return -1; - - pufbuf->offset = newoff; - return 0; -} - -int -puffs_framebuf_getwindow(struct puffs_framebuf *pufbuf, size_t winoff, - void **data, size_t *dlen) -{ - size_t winlen; - -#ifdef WINTESTING - winlen = MIN(*dlen, 32); -#else - winlen = *dlen; -#endif - - if (reservespace(pufbuf, winoff, winlen) == -1) - return -1; - - *data = pufbuf->buf + winoff; - if (pufbuf->maxoff < winoff + winlen) - pufbuf->maxoff = winoff + winlen; - - return 0; -} - -void * -puffs__framebuf_getdataptr(struct puffs_framebuf *pufbuf) -{ - - return pufbuf->buf; -} - -static void -errnotify(struct puffs_usermount *pu, struct puffs_framebuf *pufbuf, int error) -{ - - pufbuf->rv = error; - if (pufbuf->pcc) { - puffs__goto(pufbuf->pcc); - } else if (pufbuf->fcb) { - pufbuf->istat &= ~ISTAT_NODESTROY; - pufbuf->fcb(pu, pufbuf, pufbuf->fcb_arg, error); - } else { - pufbuf->istat &= ~ISTAT_NODESTROY; - puffs_framebuf_destroy(pufbuf); - } -} - -#define GETFIO(fd) \ -do { \ - fio = getfiobyfd(pu, fd); \ - if (fio == NULL) { \ - errno = EINVAL; \ - return -1; \ - } \ - if (fio->stat & FIO_WRGONE) { \ - errno = ESHUTDOWN; \ - return -1; \ - } \ -} while (/*CONSTCOND*/0) - -int -puffs_framev_enqueue_cc(struct puffs_cc *pcc, int fd, - struct puffs_framebuf *pufbuf, int flags) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - struct puffs_fctrl_io *fio; - - /* - * Technically we shouldn't allow this if RDGONE, but it's - * difficult to trap write close without allowing writes. - * And besides, there's probably a disconnect sequence in - * the protocol, so unexpectedly getting a closed fd is - * most likely an error condition. - */ - GETFIO(fd); - - pufbuf->pcc = pcc; - pufbuf->fcb = NULL; - pufbuf->fcb_arg = NULL; - - pufbuf->offset = 0; - pufbuf->istat |= ISTAT_NODESTROY; - - if (flags & PUFFS_FBQUEUE_URGENT) - TAILQ_INSERT_HEAD(&fio->snd_qing, pufbuf, pfb_entries); - else - TAILQ_INSERT_TAIL(&fio->snd_qing, pufbuf, pfb_entries); - - puffs_cc_yield(pcc); - if (pufbuf->rv) { - pufbuf->istat &= ~ISTAT_NODESTROY; - errno = pufbuf->rv; - return -1; - } - - return 0; -} - -int -puffs_framev_enqueue_cb(struct puffs_usermount *pu, int fd, - struct puffs_framebuf *pufbuf, puffs_framev_cb fcb, void *arg, - int flags) -{ - struct puffs_fctrl_io *fio; - - /* see enqueue_cc */ - GETFIO(fd); - - pufbuf->pcc = NULL; - pufbuf->fcb = fcb; - pufbuf->fcb_arg = arg; - - pufbuf->offset = 0; - pufbuf->istat |= ISTAT_NODESTROY; - - if (flags & PUFFS_FBQUEUE_URGENT) - TAILQ_INSERT_HEAD(&fio->snd_qing, pufbuf, pfb_entries); - else - TAILQ_INSERT_TAIL(&fio->snd_qing, pufbuf, pfb_entries); - - return 0; -} - -int -puffs_framev_enqueue_justsend(struct puffs_usermount *pu, int fd, - struct puffs_framebuf *pufbuf, int reply, int flags) -{ - struct puffs_fctrl_io *fio; - - assert((pufbuf->istat & ISTAT_INTERNAL) == 0); - - GETFIO(fd); - - pufbuf->pcc = NULL; - pufbuf->fcb = NULL; - pufbuf->fcb_arg = NULL; - - pufbuf->offset = 0; - pufbuf->istat |= ISTAT_NODESTROY; - if (!reply) - pufbuf->istat |= ISTAT_NOREPLY; - - if (flags & PUFFS_FBQUEUE_URGENT) - TAILQ_INSERT_HEAD(&fio->snd_qing, pufbuf, pfb_entries); - else - TAILQ_INSERT_TAIL(&fio->snd_qing, pufbuf, pfb_entries); - - return 0; -} - -/* ARGSUSED */ -int -puffs_framev_enqueue_directreceive(struct puffs_cc *pcc, int fd, - struct puffs_framebuf *pufbuf, int flags /* used in the future */) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - struct puffs_fctrl_io *fio; - - assert((pufbuf->istat & ISTAT_INTERNAL) == 0); - - fio = getfiobyfd(pu, fd); - if (fio == NULL) { - errno = EINVAL; - return -1; - } - - /* XXX: should have cur_in queue */ - assert(fio->cur_in == NULL); - fio->cur_in = pufbuf; - - pufbuf->pcc = pcc; - pufbuf->fcb = NULL; - pufbuf->fcb_arg = NULL; - - pufbuf->offset = 0; - pufbuf->istat |= ISTAT_NODESTROY | ISTAT_DIRECT; - - puffs_cc_yield(pcc); - pufbuf->istat &= ~ISTAT_NODESTROY; /* XXX: not the right place */ - if (pufbuf->rv) { - errno = pufbuf->rv; - return -1; - } - - return 0; -} - -int -puffs_framev_enqueue_directsend(struct puffs_cc *pcc, int fd, - struct puffs_framebuf *pufbuf, int flags) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - struct puffs_fctrl_io *fio; - - assert((pufbuf->istat & ISTAT_INTERNAL) == 0); - - if (flags & PUFFS_FBQUEUE_URGENT) - abort(); /* EOPNOTSUPP for now */ - - GETFIO(fd); - - pufbuf->pcc = pcc; - pufbuf->fcb = NULL; - pufbuf->fcb_arg = NULL; - - pufbuf->offset = 0; - pufbuf->istat |= ISTAT_NODESTROY | ISTAT_DIRECT; - - TAILQ_INSERT_TAIL(&fio->snd_qing, pufbuf, pfb_entries); - - puffs_cc_yield(pcc); - if (pufbuf->rv) { - pufbuf->istat &= ~ISTAT_NODESTROY; - errno = pufbuf->rv; - return -1; - } - - return 0; -} - -int -puffs_framev_framebuf_ccpromote(struct puffs_framebuf *pufbuf, - struct puffs_cc *pcc) -{ - - if ((pufbuf->istat & ISTAT_ONQUEUE) == 0) { - errno = EBUSY; - return -1; - } - - pufbuf->pcc = pcc; - pufbuf->fcb = NULL; - pufbuf->fcb_arg = NULL; - pufbuf->istat &= ~ISTAT_NOREPLY; - - puffs_cc_yield(pcc); - - return 0; -} - -int -puffs_framev_enqueue_waitevent(struct puffs_cc *pcc, int fd, int *what) -{ - struct puffs_usermount *pu = pcc->pcc_pu; - struct puffs_fctrl_io *fio; - struct puffs_fbevent feb; - struct kevent kev; - int rv, svwhat; - - svwhat = *what; - - if (*what == 0) { - errno = EINVAL; - return -1; - } - - fio = getfiobyfd(pu, fd); - if (fio == NULL) { - errno = EINVAL; - return -1; - } - - feb.pcc = pcc; - feb.what = *what & (PUFFS_FBIO_READ|PUFFS_FBIO_WRITE|PUFFS_FBIO_ERROR); - - if (*what & PUFFS_FBIO_READ) - if ((fio->stat & FIO_ENABLE_R) == 0) - EV_SET(&kev, fd, EVFILT_READ, EV_ENABLE, - 0, 0, (uintptr_t)fio); - - if (kevent(pu->pu_kq, &kev, 1, NULL, 0, NULL) == -1) - return -1; - - if (*what & PUFFS_FBIO_READ) - fio->rwait++; - if (*what & PUFFS_FBIO_WRITE) - fio->wwait++; - - LIST_INSERT_HEAD(&fio->ev_qing, &feb, pfe_entries); - puffs_cc_yield(pcc); - - assert(svwhat == *what); - - if (*what & PUFFS_FBIO_READ) { - fio->rwait--; - if (fio->rwait == 0 && (fio->stat & FIO_ENABLE_R) == 0) { - EV_SET(&kev, fd, EVFILT_READ, EV_DISABLE, - 0, 0, (uintptr_t)fio); - rv = kevent(pu->pu_kq, &kev, 1, NULL, 0, NULL); -#if 0 - if (rv != 0) - /* XXXXX oh dear */; -#endif - } - } - if (*what & PUFFS_FBIO_WRITE) - fio->wwait--; - - if (feb.rv == 0) { - *what = feb.what; - rv = 0; - } else { - *what = PUFFS_FBIO_ERROR; - errno = feb.rv; - rv = -1; - } - - return rv; -} - -void -puffs__framev_notify(struct puffs_fctrl_io *fio, int what) -{ - struct puffs_fbevent *fbevp; - - restart: - LIST_FOREACH(fbevp, &fio->ev_qing, pfe_entries) { - if (fbevp->what & what) { - fbevp->what = what; - fbevp->rv = 0; - LIST_REMOVE(fbevp, pfe_entries); - puffs_cc_continue(fbevp->pcc); - goto restart; - } - } -} - -static struct puffs_framebuf * -findbuf(struct puffs_usermount *pu, struct puffs_framectrl *fctrl, - struct puffs_fctrl_io *fio, struct puffs_framebuf *findme) -{ - struct puffs_framebuf *cand; - int notresp = 0; - - TAILQ_FOREACH(cand, &fio->res_qing, pfb_entries) - if (fctrl->cmpfb(pu, findme, cand, ¬resp) == 0 || notresp) - break; - - assert(!(notresp && cand == NULL)); - if (notresp || cand == NULL) - return NULL; - - TAILQ_REMOVE(&fio->res_qing, cand, pfb_entries); - return cand; -} - -void -puffs__framebuf_moveinfo(struct puffs_framebuf *from, struct puffs_framebuf *to) -{ - - assert(from->istat & ISTAT_INTERNAL); - - /* migrate buffer */ - free(to->buf); - to->buf = from->buf; - - /* migrate buffer info */ - to->len = from->len; - to->offset = from->offset; - to->maxoff = from->maxoff; - - from->buf = NULL; - from->len = 0; -} - -void -puffs__framev_input(struct puffs_usermount *pu, struct puffs_framectrl *fctrl, - struct puffs_fctrl_io *fio) -{ - struct puffs_framebuf *pufbuf, *appbuf; - int rv, complete; - - while ((fio->stat & FIO_DEAD) == 0 && (fio->stat & FIO_ENABLE_R)) { - if ((pufbuf = fio->cur_in) == NULL) { - pufbuf = puffs_framebuf_make(); - if (pufbuf == NULL) - return; - pufbuf->istat |= ISTAT_INTERNAL; - fio->cur_in = pufbuf; - } - - complete = 0; - rv = fctrl->rfb(pu, pufbuf, fio->io_fd, &complete); - - /* error */ - if (rv) { - puffs__framev_readclose(pu, fio, rv); - fio->cur_in = NULL; - return; - } - - /* partial read, come back to fight another day */ - if (complete == 0) - break; - - /* else: full read, process */ - fio->cur_in = NULL; - if ((pufbuf->istat & ISTAT_DIRECT) == 0) { - appbuf = findbuf(pu, fctrl, fio, pufbuf); - - /* - * No request for this frame? If fs implements - * gotfb, give frame to that. Otherwise drop it. - */ - if (appbuf == NULL) { - if (fctrl->gotfb) { - pufbuf->istat &= ~ISTAT_INTERNAL; - fctrl->gotfb(pu, pufbuf); - } else { - puffs_framebuf_destroy(pufbuf); - } - continue; - } - - puffs__framebuf_moveinfo(pufbuf, appbuf); - puffs_framebuf_destroy(pufbuf); - } else { - appbuf = pufbuf; - } - appbuf->istat &= ~ISTAT_NODESTROY; - - if (appbuf->pcc) { - puffs__cc_cont(appbuf->pcc); - } else if (appbuf->fcb) { - appbuf->fcb(pu, appbuf, appbuf->fcb_arg, 0); - } else { - puffs_framebuf_destroy(appbuf); - } - - /* hopeless romantics, here we go again */ - } -} - -int -puffs__framev_output(struct puffs_usermount *pu, struct puffs_framectrl *fctrl, - struct puffs_fctrl_io *fio) -{ - struct puffs_framebuf *pufbuf; - int rv, complete, done; - - if (fio->stat & FIO_DEAD) - return 0; - - for (pufbuf = TAILQ_FIRST(&fio->snd_qing), done = 0; - pufbuf && (fio->stat & FIO_DEAD) == 0 && fio->stat & FIO_ENABLE_W; - pufbuf = TAILQ_FIRST(&fio->snd_qing)) { - complete = 0; - rv = fctrl->wfb(pu, pufbuf, fio->io_fd, &complete); - - if (rv) { - puffs__framev_writeclose(pu, fio, rv); - done = 1; - break; - } - - /* partial write */ - if (complete == 0) - return done; - - /* else, complete write */ - TAILQ_REMOVE(&fio->snd_qing, pufbuf, pfb_entries); - - /* can't wait for result if we can't read */ - if (fio->stat & FIO_RDGONE) { - errnotify(pu, pufbuf, ENXIO); - done = 1; - } else if ((pufbuf->istat & ISTAT_DIRECT)) { - pufbuf->istat &= ~ISTAT_NODESTROY; - done = 1; - puffs__cc_cont(pufbuf->pcc); - } else if ((pufbuf->istat & ISTAT_NOREPLY) == 0) { - TAILQ_INSERT_TAIL(&fio->res_qing, pufbuf, - pfb_entries); - } else { - pufbuf->istat &= ~ISTAT_NODESTROY; - puffs_framebuf_destroy(pufbuf); - } - - /* omstart! */ - } - - return done; -} - -int -puffs__framev_addfd_ctrl(struct puffs_usermount *pu, int fd, int what, - struct puffs_framectrl *pfctrl) -{ - struct puffs_fctrl_io *fio; - struct kevent *newevs; - struct kevent kev[2]; - size_t nevs; - int rv, readenable; - - nevs = pu->pu_nevs+2; - newevs = realloc(pu->pu_evs, nevs*sizeof(struct kevent)); - if (newevs == NULL) - return -1; - pu->pu_evs = newevs; - - fio = malloc(sizeof(struct puffs_fctrl_io)); - if (fio == NULL) - return -1; - memset(fio, 0, sizeof(struct puffs_fctrl_io)); - fio->io_fd = fd; - fio->cur_in = NULL; - fio->fctrl = pfctrl; - TAILQ_INIT(&fio->snd_qing); - TAILQ_INIT(&fio->res_qing); - LIST_INIT(&fio->ev_qing); - - readenable = 0; - if ((what & PUFFS_FBIO_READ) == 0) - readenable = EV_DISABLE; - - if (pu->pu_state & PU_INLOOP) { - EV_SET(&kev[0], fd, EVFILT_READ, - EV_ADD|readenable, 0, 0, (intptr_t)fio); - EV_SET(&kev[1], fd, EVFILT_WRITE, - EV_ADD|EV_DISABLE, 0, 0, (intptr_t)fio); - rv = kevent(pu->pu_kq, kev, 2, NULL, 0, NULL); - if (rv == -1) { - free(fio); - return -1; - } - } - if (what & PUFFS_FBIO_READ) - fio->stat |= FIO_ENABLE_R; - if (what & PUFFS_FBIO_WRITE) - fio->stat |= FIO_ENABLE_W; - - LIST_INSERT_HEAD(&pu->pu_ios, fio, fio_entries); - pu->pu_nevs = nevs; - - return 0; -} - -int -puffs_framev_addfd(struct puffs_usermount *pu, int fd, int what) -{ - - return puffs__framev_addfd_ctrl(pu, fd, what, - &pu->pu_framectrl[PU_FRAMECTRL_USER]); -} - -/* - * XXX: the following en/disable should be coalesced and executed - * only during the actual kevent call. So feel free to fix if - * threatened by mindblowing boredom. - */ - -int -puffs_framev_enablefd(struct puffs_usermount *pu, int fd, int what) -{ - struct kevent kev; - struct puffs_fctrl_io *fio; - int rv = 0; - - assert((what & (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) != 0); - - fio = getfiobyfd(pu, fd); - if (fio == NULL) { - errno = ENXIO; - return -1; - } - - /* write is enabled in the event loop if there is output */ - if (what & PUFFS_FBIO_READ && fio->rwait == 0) { - EV_SET(&kev, fd, EVFILT_READ, EV_ENABLE, 0, 0, (uintptr_t)fio); - rv = kevent(pu->pu_kq, &kev, 1, NULL, 0, NULL); - } - - if (rv == 0) { - if (what & PUFFS_FBIO_READ) - fio->stat |= FIO_ENABLE_R; - if (what & PUFFS_FBIO_WRITE) - fio->stat |= FIO_ENABLE_W; - } - - return rv; -} - -int -puffs_framev_disablefd(struct puffs_usermount *pu, int fd, int what) -{ - struct kevent kev[2]; - struct puffs_fctrl_io *fio; - size_t i; - int rv; - - assert((what & (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) != 0); - - fio = getfiobyfd(pu, fd); - if (fio == NULL) { - errno = ENXIO; - return -1; - } - - i = 0; - if (what & PUFFS_FBIO_READ && fio->rwait == 0) { - EV_SET(&kev[0], fd, - EVFILT_READ, EV_DISABLE, 0, 0, (uintptr_t)fio); - i++; - } - if (what & PUFFS_FBIO_WRITE && fio->stat & FIO_WR && fio->wwait == 0) { - EV_SET(&kev[1], fd, - EVFILT_WRITE, EV_DISABLE, 0, 0, (uintptr_t)fio); - i++; - } - if (i) - rv = kevent(pu->pu_kq, kev, i, NULL, 0, NULL); - else - rv = 0; - - if (rv == 0) { - if (what & PUFFS_FBIO_READ) - fio->stat &= ~FIO_ENABLE_R; - if (what & PUFFS_FBIO_WRITE) - fio->stat &= ~FIO_ENABLE_W; - } - - return rv; -} - -void -puffs__framev_readclose(struct puffs_usermount *pu, - struct puffs_fctrl_io *fio, int error) -{ - struct puffs_framebuf *pufbuf; - struct kevent kev; - int notflag; - - if (fio->stat & FIO_RDGONE || fio->stat & FIO_DEAD) - return; - fio->stat |= FIO_RDGONE; - - if (fio->cur_in) { - if ((fio->cur_in->istat & ISTAT_DIRECT) == 0) { - puffs_framebuf_destroy(fio->cur_in); - fio->cur_in = NULL; - } else { - errnotify(pu, fio->cur_in, error); - } - } - - while ((pufbuf = TAILQ_FIRST(&fio->res_qing)) != NULL) { - TAILQ_REMOVE(&fio->res_qing, pufbuf, pfb_entries); - errnotify(pu, pufbuf, error); - } - - EV_SET(&kev, fio->io_fd, EVFILT_READ, EV_DELETE, 0, 0, 0); - (void) kevent(pu->pu_kq, &kev, 1, NULL, 0, NULL); - - notflag = PUFFS_FBIO_READ; - if (fio->stat & FIO_WRGONE) - notflag |= PUFFS_FBIO_WRITE; - - if (fio->fctrl->fdnotfn) - fio->fctrl->fdnotfn(pu, fio->io_fd, notflag); -} - -void -puffs__framev_writeclose(struct puffs_usermount *pu, - struct puffs_fctrl_io *fio, int error) -{ - struct puffs_framebuf *pufbuf; - struct kevent kev; - int notflag; - - if (fio->stat & FIO_WRGONE || fio->stat & FIO_DEAD) - return; - fio->stat |= FIO_WRGONE; - - while ((pufbuf = TAILQ_FIRST(&fio->snd_qing)) != NULL) { - TAILQ_REMOVE(&fio->snd_qing, pufbuf, pfb_entries); - errnotify(pu, pufbuf, error); - } - - EV_SET(&kev, fio->io_fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0); - (void) kevent(pu->pu_kq, &kev, 1, NULL, 0, NULL); - - notflag = PUFFS_FBIO_WRITE; - if (fio->stat & FIO_RDGONE) - notflag |= PUFFS_FBIO_READ; - - if (fio->fctrl->fdnotfn) - fio->fctrl->fdnotfn(pu, fio->io_fd, notflag); -} - -static int -removefio(struct puffs_usermount *pu, struct puffs_fctrl_io *fio, int error) -{ - struct puffs_fbevent *fbevp; - - LIST_REMOVE(fio, fio_entries); - if (pu->pu_state & PU_INLOOP) { - puffs__framev_readclose(pu, fio, error); - puffs__framev_writeclose(pu, fio, error); - } - - while ((fbevp = LIST_FIRST(&fio->ev_qing)) != NULL) { - fbevp->rv = error; - LIST_REMOVE(fbevp, pfe_entries); - puffs__goto(fbevp->pcc); - } - - /* don't bother with realloc */ - pu->pu_nevs -= 2; - - /* don't free us yet, might have some references in event arrays */ - fio->stat |= FIO_DEAD; - LIST_INSERT_HEAD(&pu->pu_ios_rmlist, fio, fio_entries); - - return 0; - -} - -int -puffs_framev_removefd(struct puffs_usermount *pu, int fd, int error) -{ - struct puffs_fctrl_io *fio; - - fio = getfiobyfd(pu, fd); - if (fio == NULL) { - errno = ENXIO; - return -1; - } - - return removefio(pu, fio, error ? error : ECONNRESET); -} - -void -puffs_framev_removeonclose(struct puffs_usermount *pu, int fd, int what) -{ - - if (what == (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) - (void) puffs_framev_removefd(pu, fd, ECONNRESET); -} - -void -puffs_framev_unmountonclose(struct puffs_usermount *pu, int fd, int what) -{ - - /* XXX & X: unmount is non-sensible */ - puffs_framev_removeonclose(pu, fd, what); - if (what == (PUFFS_FBIO_READ | PUFFS_FBIO_WRITE)) - PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED); -} - -void -puffs_framev_init(struct puffs_usermount *pu, - puffs_framev_readframe_fn rfb, puffs_framev_writeframe_fn wfb, - puffs_framev_cmpframe_fn cmpfb, puffs_framev_gotframe_fn gotfb, - puffs_framev_fdnotify_fn fdnotfn) -{ - struct puffs_framectrl *pfctrl; - - pfctrl = &pu->pu_framectrl[PU_FRAMECTRL_USER]; - pfctrl->rfb = rfb; - pfctrl->wfb = wfb; - pfctrl->cmpfb = cmpfb; - pfctrl->gotfb = gotfb; - pfctrl->fdnotfn = fdnotfn; -} - -void -puffs__framev_exit(struct puffs_usermount *pu) -{ - struct puffs_fctrl_io *fio; - - while ((fio = LIST_FIRST(&pu->pu_ios)) != NULL) - removefio(pu, fio, ENXIO); - free(pu->pu_evs); - - /* closing pu->pu_kq takes care of puffsfd */ -} diff --git a/lib/libpuffs/null.c b/lib/libpuffs/null.c deleted file mode 100644 index 763f48049..000000000 --- a/lib/libpuffs/null.c +++ /dev/null @@ -1,683 +0,0 @@ -/* $NetBSD: null.c,v 1.33 2011/11/25 15:02:02 manu Exp $ */ - -/* - * Copyright (c) 2007 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: null.c,v 1.33 2011/11/25 15:02:02 manu Exp $"); -#endif /* !lint */ - -/* - * A "nullfs" using puffs, i.e. maps one location in the hierarchy - * to another using standard system calls. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -PUFFSOP_PROTOS(puffs_null) - -/* - * set attributes to what is specified. XXX: no rollback in case of failure - */ -static int -processvattr(const char *path, const struct vattr *va, int regular) -{ - struct timeval tv[2]; - - /* XXX: -1 == PUFFS_VNOVAL, but shouldn't trust that */ - if (va->va_uid != (unsigned)-1 || va->va_gid != (unsigned)-1) - if (lchown(path, va->va_uid, va->va_gid) == -1) - return errno; - - if (va->va_mode != (unsigned)PUFFS_VNOVAL) - if (lchmod(path, va->va_mode) == -1) - return errno; - - /* sloppy */ - if (va->va_atime.tv_sec != (time_t)PUFFS_VNOVAL - || va->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL) { - TIMESPEC_TO_TIMEVAL(&tv[0], &va->va_atime); - TIMESPEC_TO_TIMEVAL(&tv[1], &va->va_mtime); - - if (lutimes(path, tv) == -1) - return errno; - } - - if (regular && va->va_size != (u_quad_t)PUFFS_VNOVAL) - if (truncate(path, (off_t)va->va_size) == -1) - return errno; - - return 0; -} - -/* - * Kludge to open files which aren't writable *any longer*. This kinda - * works because the vfs layer does validation checks based on the file's - * permissions to allow writable opening before opening them. However, - * the problem arises if we want to create a file, write to it (cache), - * adjust permissions and then flush the file. - */ -static int -writeableopen(const char *path) -{ - struct stat sb; - mode_t origmode; - int sverr = 0; - int fd; - - fd = open(path, O_WRONLY); - if (fd == -1) { - if (errno == EACCES) { - if (stat(path, &sb) == -1) - return -1; - origmode = sb.st_mode & ALLPERMS; - - if (chmod(path, 0200) == -1) - return -1; - - fd = open(path, O_WRONLY); - if (fd == -1) - sverr = errno; - - chmod(path, origmode); - if (sverr) - errno = sverr; - } else - return -1; - } - - return fd; -} - -/*ARGSUSED*/ -static void * -inodecmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) -{ - ino_t *cmpino = arg; - - if (pn->pn_va.va_fileid == *cmpino) - return pn; - return NULL; -} - -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; -} - -/* This should be called first and overriden from the file system */ -void -puffs_null_setops(struct puffs_ops *pops) -{ - - PUFFSOP_SET(pops, puffs_null, fs, statvfs); - PUFFSOP_SETFSNOP(pops, unmount); - PUFFSOP_SETFSNOP(pops, sync); - PUFFSOP_SET(pops, puffs_null, fs, fhtonode); - PUFFSOP_SET(pops, puffs_null, fs, nodetofh); - - PUFFSOP_SET(pops, puffs_null, node, lookup); - PUFFSOP_SET(pops, puffs_null, node, create); - PUFFSOP_SET(pops, puffs_null, node, mknod); - PUFFSOP_SET(pops, puffs_null, node, getattr); - PUFFSOP_SET(pops, puffs_null, node, setattr); - PUFFSOP_SET(pops, puffs_null, node, fsync); - PUFFSOP_SET(pops, puffs_null, node, remove); - PUFFSOP_SET(pops, puffs_null, node, link); - PUFFSOP_SET(pops, puffs_null, node, rename); - PUFFSOP_SET(pops, puffs_null, node, mkdir); - PUFFSOP_SET(pops, puffs_null, node, rmdir); - PUFFSOP_SET(pops, puffs_null, node, symlink); - PUFFSOP_SET(pops, puffs_null, node, readlink); - PUFFSOP_SET(pops, puffs_null, node, readdir); - PUFFSOP_SET(pops, puffs_null, node, read); - PUFFSOP_SET(pops, puffs_null, node, write); - PUFFSOP_SET(pops, puffs_genfs, node, reclaim); -} - -/*ARGSUSED*/ -int -puffs_null_fs_statvfs(struct puffs_usermount *pu, struct statvfs *svfsb) -{ - - if (statvfs(PNPATH(puffs_getroot(pu)), svfsb) == -1) - return errno; - - return 0; -} - -/* - * XXX: this is the stupidest crap ever, but: - * getfh() returns the fhandle type, when we are expected to deliver - * the fid type. Just adjust it a bit and stop whining. - * - * Yes, this really really needs fixing. Yes, *REALLY*. - */ -#define FHANDLE_HEADERLEN 8 -struct kernfid { - unsigned short fid_len; /* length of data in bytes */ - unsigned short fid_reserved; /* compat: historic align */ - char fid_data[0]; /* data (variable length) */ -}; - -/*ARGSUSED*/ -static void * -fhcmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) -{ - struct kernfid *kf1, *kf2; - - if ((kf1 = pn->pn_data) == NULL) - return NULL; - kf2 = arg; - - if (kf1->fid_len != kf2->fid_len) - return NULL; - - /*LINTED*/ - if (memcmp(kf1, kf2, kf1->fid_len) == 0) - return pn; - return NULL; -} - -/* - * This routine only supports file handles which have been issued while - * the server was alive. Not really stable ones, that is. - */ -/*ARGSUSED*/ -int -puffs_null_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize, - struct puffs_newinfo *pni) -{ - struct puffs_node *pn_res; - - pn_res = puffs_pn_nodewalk(pu, fhcmp, fid); - if (pn_res == NULL) - return ENOENT; - - puffs_newinfo_setcookie(pni, pn_res); - puffs_newinfo_setvtype(pni, pn_res->pn_va.va_type); - puffs_newinfo_setsize(pni, (voff_t)pn_res->pn_va.va_size); - puffs_newinfo_setrdev(pni, pn_res->pn_va.va_rdev); - 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; - struct kernfid *kfid; - void *bounce; - int rv; - - rv = 0; - bounce = NULL; - if (*fidsize) { - bounce = malloc(*fidsize + FHANDLE_HEADERLEN); - if (!bounce) - return ENOMEM; - *fidsize += FHANDLE_HEADERLEN; - } - if (getfh(PNPATH(pn), bounce, fidsize) == -1) - rv = errno; - else - memcpy(fid, (uint8_t *)bounce + FHANDLE_HEADERLEN, - *fidsize - FHANDLE_HEADERLEN); - kfid = fid; - if (rv == 0) { - *fidsize = kfid->fid_len; - pn->pn_data = malloc(*fidsize); - if (pn->pn_data == NULL) - abort(); /* lazy */ - memcpy(pn->pn_data, fid, *fidsize); - } else { - *fidsize -= FHANDLE_HEADERLEN; - } - free(bounce); - - return rv; -} - -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, (voff_t)pn_res->pn_va.va_size); - puffs_newinfo_setrdev(pni, pn_res->pn_va.va_rdev); - - return 0; -} - -/*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_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); - if (mknod(PCNPATH(pcn), mode, va->va_rdev) == -1) - return errno; - - rv = makenode(pu, pni, pcn, va, 0); - if (rv) - unlink(PCNPATH(pcn)); - return rv; -} - -/*ARGSUSED*/ -int -puffs_null_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, - struct vattr *va, const struct puffs_cred *pcred) -{ - struct puffs_node *pn = opc; - struct stat sb; - - if (lstat(PNPATH(pn), &sb) == -1) - return errno; - puffs_stat2vattr(va, &sb); - - return 0; -} - -/*ARGSUSED*/ -int -puffs_null_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc, - const struct vattr *va, const struct puffs_cred *pcred) -{ - struct puffs_node *pn = opc; - int rv; - - rv = processvattr(PNPATH(pn), va, pn->pn_va.va_type == VREG); - if (rv) - return rv; - - puffs_setvattr(&pn->pn_va, va); - - return 0; -} - -/*ARGSUSED*/ -int -puffs_null_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc, - const struct puffs_cred *pcred, int how, - off_t offlo, off_t offhi) -{ - struct puffs_node *pn = opc; - int fd, rv; - int fflags; - struct stat sb; - - rv = 0; - if (stat(PNPATH(pn), &sb) == -1) - return errno; - if (S_ISDIR(sb.st_mode)) { - DIR *dirp; - if ((dirp = opendir(PNPATH(pn))) == 0) - return errno; - fd = dirfd(dirp); - if (fd == -1) - return errno; - - if (fsync(fd) == -1) - rv = errno; - } else { - fd = writeableopen(PNPATH(pn)); - if (fd == -1) - return errno; - - if (how & PUFFS_FSYNC_DATAONLY) - fflags = FDATASYNC; - else - fflags = FFILESYNC; - if (how & PUFFS_FSYNC_CACHE) - fflags |= FDISKSYNC; - - if (fsync_range(fd, fflags, offlo, offhi - offlo) == -1) - rv = errno; - } - - close(fd); - - return rv; -} - -/*ARGSUSED*/ -int -puffs_null_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, - puffs_cookie_t targ, const struct puffs_cn *pcn) -{ - struct puffs_node *pn_targ = targ; - - if (unlink(PNPATH(pn_targ)) == -1) - return errno; - puffs_pn_remove(pn_targ); - - return 0; -} - -/*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; -} - -/*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) -{ - struct puffs_node *pn_targ = targ; - - if (rename(PCNPATH(pcn_src), PCNPATH(pcn_targ)) == -1) - return errno; - - if (pn_targ) - puffs_pn_remove(pn_targ); - - return 0; -} - -/*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_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc, - puffs_cookie_t targ, const struct puffs_cn *pcn) -{ - struct puffs_node *pn_targ = targ; - - if (rmdir(PNPATH(pn_targ)) == -1) - return errno; - puffs_pn_remove(pn_targ); - - 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_readlink(struct puffs_usermount *pu, puffs_cookie_t opc, - const struct puffs_cred *pcred, char *linkname, size_t *linklen) -{ - struct puffs_node *pn = opc; - ssize_t rv; - - rv = readlink(PNPATH(pn), linkname, *linklen); - if (rv == -1) - return errno; - - *linklen = rv; - return 0; -} - -/*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 != 0) - goto out; - - if (!result) { - *eofflag = 1; - 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; -} - -/*ARGSUSED*/ -int -puffs_null_node_read(struct puffs_usermount *pu, puffs_cookie_t opc, - uint8_t *buf, off_t offset, size_t *buflen, - const struct puffs_cred *pcred, int ioflag) -{ - struct puffs_node *pn = opc; - ssize_t n; - off_t off; - int fd, rv; - - rv = 0; - fd = open(PNPATH(pn), O_RDONLY); - if (fd == -1) - return errno; - off = lseek(fd, offset, SEEK_SET); - if (off == -1) { - rv = errno; - goto out; - } - - n = read(fd, buf, *buflen); - if (n == -1) - rv = errno; - else - *buflen -= n; - - out: - close(fd); - return rv; -} - -/*ARGSUSED*/ -int -puffs_null_node_write(struct puffs_usermount *pu, puffs_cookie_t opc, - uint8_t *buf, off_t offset, size_t *buflen, - const struct puffs_cred *pcred, int ioflag) -{ - struct puffs_node *pn = opc; - ssize_t n; - off_t off; - int fd, rv; - - rv = 0; - fd = writeableopen(PNPATH(pn)); - if (fd == -1) - return errno; - - off = lseek(fd, offset, SEEK_SET); - if (off == -1) { - rv = errno; - goto out; - } - - n = write(fd, buf, *buflen); - if (n == -1) - rv = errno; - else - *buflen -= n; - - out: - close(fd); - return rv; -} diff --git a/lib/libpuffs/opdump.c b/lib/libpuffs/opdump.c deleted file mode 100644 index 27cf396f6..000000000 --- a/lib/libpuffs/opdump.c +++ /dev/null @@ -1,542 +0,0 @@ -/* $NetBSD: opdump.c,v 1.37 2014/10/31 13:56:04 manu Exp $ */ - -/* - * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Google Summer of Code program and the Ulla Tuominen Foundation. - * The Google SoC project was mentored by Bill Studenmund. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Pretty-printing helper routines for VFS/VOP request contents */ - -/* yes, this is pretty much a mess */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: opdump.c,v 1.37 2014/10/31 13:56:04 manu Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include -#include -#include - -#include "puffs_priv.h" - -#define DINT " " - -const char *puffsdump_vfsop_revmap[] = { - "PUFFS_VFS_MOUNT", - "PUFFS_VFS_START", - "PUFFS_VFS_UNMOUNT", - "PUFFS_VFS_ROOT", - "PUFFS_VFS_QUOTACTL", - "PUFFS_VFS_STATVFS", - "PUFFS_VFS_SYNC", - "PUFFS_VFS_VGET", - "PUFFS_VFS_FHTOVP", - "PUFFS_VFS_VPTOFH", - "PUFFS_VFS_INIT", - "PUFFS_VFS_DONE", - "PUFFS_VFS_SNAPSHOT", - "PUFFS_VFS_EXTATTRCTL", - "PUFFS_VFS_SUSPEND" -}; -size_t puffsdump_vfsop_count = __arraycount(puffsdump_vfsop_revmap); - -const char *puffsdump_vnop_revmap[] = { - "PUFFS_VN_LOOKUP", - "PUFFS_VN_CREATE", - "PUFFS_VN_MKNOD", - "PUFFS_VN_OPEN", - "PUFFS_VN_CLOSE", - "PUFFS_VN_ACCESS", - "PUFFS_VN_GETATTR", - "PUFFS_VN_SETATTR", - "PUFFS_VN_READ", - "PUFFS_VN_WRITE", - "PUFFS_VN_IOCTL", - "PUFFS_VN_FCNTL", - "PUFFS_VN_POLL", - "PUFFS_VN_KQFILTER", - "PUFFS_VN_REVOKE", - "PUFFS_VN_MMAP", - "PUFFS_VN_FSYNC", - "PUFFS_VN_SEEK", - "PUFFS_VN_REMOVE", - "PUFFS_VN_LINK", - "PUFFS_VN_RENAME", - "PUFFS_VN_MKDIR", - "PUFFS_VN_RMDIR", - "PUFFS_VN_SYMLINK", - "PUFFS_VN_READDIR", - "PUFFS_VN_READLINK", - "PUFFS_VN_ABORTOP", - "PUFFS_VN_INACTIVE", - "PUFFS_VN_RECLAIM", - "PUFFS_VN_LOCK", - "PUFFS_VN_UNLOCK", - "PUFFS_VN_BMAP", - "PUFFS_VN_STRATEGY", - "PUFFS_VN_PRINT", - "PUFFS_VN_ISLOCKED", - "PUFFS_VN_PATHCONF", - "PUFFS_VN_ADVLOCK", - "PUFFS_VN_LEASE", - "PUFFS_VN_WHITEOUT", - "PUFFS_VN_GETPAGES", - "PUFFS_VN_PUTPAGES", - "PUFFS_VN_GETEXTATTR", - "PUFFS_VN_LISTEXTATTR", - "PUFFS_VN_OPENEXTATTR", - "PUFFS_VN_DELETEEXTATTR", - "PUFFS_VN_SETEXTATTR", - "PUFFS_VN_CLOSEEXTATTR", - "PUFFS_VN_FALLOCATE", - "PUFFS_VN_FDISCARD", -}; -size_t puffsdump_vnop_count = __arraycount(puffsdump_vnop_revmap); - -/* XXX! */ -const char *puffsdump_cacheop_revmap[] = { - "PUFFS_CACHE_WRITE" -}; - -const char *puffsdump_errnot_revmap[] = { - "PUFFS_ERR_ERROR", - "PUFFS_ERR_MAKENODE", - "PUFFS_ERR_LOOKUP", - "PUFFS_ERR_READDIR", - "PUFFS_ERR_READLINK", - "PUFFS_ERR_READ", - "PUFFS_ERR_WRITE", - "PUFFS_ERR_VPTOFH", - "PUFFS_ERR_GETEXTATTR", - "PUFFS_ERR_LISTEXTATTR", -}; -size_t puffsdump_errnot_count = __arraycount(puffsdump_errnot_revmap); - -const char *puffsdump_flush_revmap[] = { - "PUFFS_INVAL_NAMECACHE_NODE", - "PUFFS_INVAL_NAMECACHE_DIR", - "PUFFS_INVAL_NAMECACHE_ALL", - "PUFFS_INVAL_PAGECACHE_NODE_RANGE", - "PUFFS_FLUSH_PAGECACHE_NODE_RANGE", -}; -size_t puffsdump_flush_count = __arraycount(puffsdump_flush_revmap); - -static __printflike(1, 2) void -mydprintf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -void -puffsdump_req(struct puffs_req *preq) -{ - char buf[128]; - static struct timeval tv_prev; - struct timeval tv_now, tv; - const char **map; - const char *optype; - size_t maxhandle; - int opclass, isvn = 0; - - mydprintf("reqid: %" PRIu64 ", ", preq->preq_id); - opclass = PUFFSOP_OPCLASS(preq->preq_opclass); - switch (opclass) { - case PUFFSOP_VFS: - map = puffsdump_vfsop_revmap; - maxhandle = puffsdump_vfsop_count; - break; - case PUFFSOP_VN: - map = puffsdump_vnop_revmap; - maxhandle = puffsdump_vnop_count; - isvn = 1; - break; - case PUFFSOP_CACHE: - map = puffsdump_cacheop_revmap; - maxhandle = __arraycount(puffsdump_cacheop_revmap); - break; - case PUFFSOP_ERROR: - map = puffsdump_errnot_revmap; - maxhandle = puffsdump_errnot_count; - break; - case PUFFSOP_FLUSH: - map = puffsdump_flush_revmap; - maxhandle = puffsdump_flush_count; - break; - default: - mydprintf("unhandled opclass %d\n", opclass); - return; - } - - if (preq->preq_optype < maxhandle) { - optype = map[preq->preq_optype]; - } else { - snprintf(buf, sizeof(buf), "UNKNOWN (%d)", preq->preq_optype); - optype = buf; - } - - mydprintf("opclass %d%s, optype: %s, " - "cookie: %p,\n" DINT "aux: %p, auxlen: %zu, pid: %d, lwpid: %d\n", - opclass, PUFFSOP_WANTREPLY(preq->preq_opclass) ? "" : " (FAF)", - optype, preq->preq_cookie, - preq->preq_buf, preq->preq_buflen, - preq->preq_pid, preq->preq_lid); - - if (isvn) { - switch (preq->preq_optype) { - case PUFFS_VN_LOOKUP: - puffsdump_lookup(preq); - break; - case PUFFS_VN_READ: - case PUFFS_VN_WRITE: - puffsdump_readwrite(preq); - break; - case PUFFS_VN_OPEN: - puffsdump_open(preq); - break; - case PUFFS_VN_REMOVE: - case PUFFS_VN_RMDIR: - case PUFFS_VN_LINK: - puffsdump_targ(preq); - break; - case PUFFS_VN_READDIR: - puffsdump_readdir(preq); - break; - case PUFFS_VN_CREATE: - case PUFFS_VN_MKDIR: - case PUFFS_VN_MKNOD: - case PUFFS_VN_SYMLINK: - puffsdump_create(preq); - break; - case PUFFS_VN_SETATTR: - puffsdump_attr(preq); - break; - default: - break; - } - } - - PU_LOCK(); - gettimeofday(&tv_now, NULL); - timersub(&tv_now, &tv_prev, &tv); - mydprintf(DINT "since previous call: %lld.%06ld\n", - (long long)tv.tv_sec, (long)tv.tv_usec); - gettimeofday(&tv_prev, NULL); - PU_UNLOCK(); -} - -void -puffsdump_rv(struct puffs_req *preq) -{ - - if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { - switch (preq->preq_optype) { - case PUFFS_VN_LOOKUP: - puffsdump_lookup_rv(preq); - break; - case PUFFS_VN_CREATE: - case PUFFS_VN_MKDIR: - case PUFFS_VN_MKNOD: - case PUFFS_VN_SYMLINK: - puffsdump_create_rv(preq); - break; - case PUFFS_VN_READ: - case PUFFS_VN_WRITE: - puffsdump_readwrite_rv(preq); - break; - case PUFFS_VN_READDIR: - puffsdump_readdir_rv(preq); - break; - case PUFFS_VN_GETATTR: - puffsdump_attr(preq); - break; - default: - break; - } - } - - mydprintf("RV reqid: %" PRIu64 ", result: %d %s\n", - preq->preq_id, preq->preq_rv, - preq->preq_rv ? strerror(preq->preq_rv) : ""); -} - -/* - * Slightly tedious print-routine so that we get a nice NOVAL instead - * of some tedious output representations for -1, especially (uint64_t)-1 - * - * We use typecasting to make this work beyond time_t/dev_t size changes. - */ -static void -dumpattr(struct vattr *vap) -{ - const char * const vtypes[] = { VNODE_TYPES }; - char buf[128]; - -/* XXX: better readability. and this is debug, so no cycle-sweat */ -#define DEFAULTBUF() snprintf(buf, sizeof(buf), "NOVAL") - - mydprintf(DINT "vattr:\n"); - mydprintf(DINT DINT "type: %s, ", vtypes[vap->va_type]); - - DEFAULTBUF(); - if (vap->va_mode != (mode_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "0%o", vap->va_mode); - mydprintf("mode: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_nlink != (nlink_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%d", vap->va_nlink); - mydprintf("nlink: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_uid != (uid_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%d", vap->va_uid); - mydprintf("uid: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_gid != (gid_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%d", vap->va_gid); - mydprintf("gid: %s\n", buf); - - DEFAULTBUF(); - if ((unsigned long long)vap->va_fsid!=(unsigned long long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "0x%llx", - (unsigned long long)vap->va_fsid); - mydprintf(DINT DINT "fsid: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_fileid != (ino_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_fileid); - mydprintf("ino: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_size != (u_quad_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_size); - mydprintf("size: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_blocksize != (long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%ld", vap->va_blocksize); - mydprintf("bsize: %s\n", buf); - - DEFAULTBUF(); - if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%lld", - (long long)vap->va_atime.tv_sec); - mydprintf(DINT DINT "a.s: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_atime.tv_nsec != (long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%ld", vap->va_atime.tv_nsec); - mydprintf("a.ns: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%lld", - (long long)vap->va_mtime.tv_sec); - mydprintf("m.s: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_mtime.tv_nsec != (long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%ld", vap->va_mtime.tv_nsec); - mydprintf("m.ns: %s\n", buf); - - DEFAULTBUF(); - if (vap->va_ctime.tv_sec != (time_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%lld", - (long long)vap->va_ctime.tv_sec); - mydprintf(DINT DINT "c.s: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_ctime.tv_nsec != (long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%ld", vap->va_ctime.tv_nsec); - mydprintf("c.ns: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_birthtime.tv_sec != (time_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%lld", - (long long)vap->va_birthtime.tv_sec); - mydprintf("b.s: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_birthtime.tv_nsec != (long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%ld", vap->va_birthtime.tv_nsec); - mydprintf("b.ns: %s\n", buf); - - DEFAULTBUF(); - if (vap->va_gen != (u_long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%lu", vap->va_gen); - mydprintf(DINT DINT "gen: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_flags != (u_long)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "0x%lx", vap->va_flags); - mydprintf("flags: %s, ", buf); - - DEFAULTBUF(); - if (vap->va_rdev != (dev_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "0x%llx", - (unsigned long long)vap->va_rdev); - mydprintf("rdev: %s\n", buf); - - DEFAULTBUF(); - if (vap->va_bytes != (u_quad_t)PUFFS_VNOVAL) - snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_bytes); - mydprintf(DINT DINT "bytes: %s, ", buf); - - snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_filerev); - mydprintf("filerev: %s, ", buf); - - snprintf(buf, sizeof(buf), "0x%x", vap->va_vaflags); - mydprintf("vaflags: %s\n", buf); -} - -void -puffsdump_cookie(puffs_cookie_t c, const char *cookiename) -{ - - mydprintf("%scookie: at %p\n", cookiename, c); -} - -static const char *cn_opnames[] = { - "LOOKUP", - "CREATE", - "DELETE", - "RENAME" -}; - -void -puffsdump_cn(struct puffs_kcn *pkcn) -{ - - mydprintf(DINT "puffs_cn: \"%s\", len %zu op %s (flags 0x%x)\n", - pkcn->pkcn_name, pkcn->pkcn_namelen, - cn_opnames[pkcn->pkcn_nameiop & NAMEI_OPMASK], - pkcn->pkcn_flags); -} - -void -puffsdump_lookup(struct puffs_req *preq) -{ - struct puffs_vnmsg_lookup *lookup_msg = (void *)preq; - - puffsdump_cn(&lookup_msg->pvnr_cn); -} - -void -puffsdump_lookup_rv(struct puffs_req *preq) -{ - struct puffs_vnmsg_lookup *lookup_msg = (void *)preq; - - mydprintf(DINT "new %p, type 0x%x, size 0x%"PRIu64", dev 0x%llx\n", - lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype, - lookup_msg->pvnr_size, (unsigned long long)lookup_msg->pvnr_rdev); -} - -void -puffsdump_create(struct puffs_req *preq) -{ - /* XXX: wrong type, but we know it fits the slot */ - struct puffs_vnmsg_create *create_msg = (void *)preq; - - dumpattr(&create_msg->pvnr_va); -} - -void -puffsdump_create_rv(struct puffs_req *preq) -{ - /* XXX: wrong type, but we know it fits the slot */ - struct puffs_vnmsg_create *create_msg = (void *)preq; - - mydprintf(DINT "new %p\n", create_msg->pvnr_newnode); -} - -void -puffsdump_readwrite(struct puffs_req *preq) -{ - struct puffs_vnmsg_rw *rw_msg = (void *)preq; - - mydprintf(DINT "offset: %" PRId64 ", resid %zu, ioflag 0x%x\n", - rw_msg->pvnr_offset, rw_msg->pvnr_resid, rw_msg->pvnr_ioflag); -} - -void -puffsdump_readwrite_rv(struct puffs_req *preq) -{ - struct puffs_vnmsg_rw *rw_msg = (void *)preq; - - mydprintf(DINT "resid after op: %zu\n", rw_msg->pvnr_resid); -} - -void -puffsdump_readdir_rv(struct puffs_req *preq) -{ - struct puffs_vnmsg_readdir *readdir_msg = (void *)preq; - - mydprintf(DINT "resid after op: %zu, eofflag %d\n", - readdir_msg->pvnr_resid, readdir_msg->pvnr_eofflag); -} - -void -puffsdump_open(struct puffs_req *preq) -{ - struct puffs_vnmsg_open *open_msg = (void *)preq; - - mydprintf(DINT "mode: 0x%x\n", open_msg->pvnr_mode); -} - -void -puffsdump_targ(struct puffs_req *preq) -{ - struct puffs_vnmsg_remove *remove_msg = (void *)preq; /* XXX! */ - - mydprintf(DINT "target cookie: %p\n", remove_msg->pvnr_cookie_targ); -} - -void -puffsdump_readdir(struct puffs_req *preq) -{ - struct puffs_vnmsg_readdir *readdir_msg = (void *)preq; - - mydprintf(DINT "read offset: %" PRId64 "\n", readdir_msg->pvnr_offset); -} - -void -puffsdump_attr(struct puffs_req *preq) -{ - struct puffs_vnmsg_setgetattr *attr_msg = (void *)preq; - - dumpattr(&attr_msg->pvnr_va); -} diff --git a/lib/libpuffs/paths.c b/lib/libpuffs/paths.c deleted file mode 100644 index 50f4cbb63..000000000 --- a/lib/libpuffs/paths.c +++ /dev/null @@ -1,299 +0,0 @@ -/* $NetBSD: paths.c,v 1.8 2008/08/12 19:44:39 pooka Exp $ */ - -/* - * Copyright (c) 2007 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: paths.c,v 1.8 2008/08/12 19:44:39 pooka Exp $"); -#endif /* !lint */ - -#include - -#include -#include -#include -#include - -#include "puffs_priv.h" - -/* - * Generic routines for pathbuilding code - */ - -int -puffs_path_pcnbuild(struct puffs_usermount *pu, struct puffs_cn *pcn, - puffs_cookie_t parent) -{ - struct puffs_node *pn_parent = PU_CMAP(pu, parent); - struct puffs_cn pcn_orig; - struct puffs_pathobj po; - int rv; - - assert(pn_parent->pn_po.po_path != NULL); - assert(pu->pu_flags & PUFFS_FLAG_BUILDPATH); - - if (pu->pu_pathtransform) { - rv = pu->pu_pathtransform(pu, &pn_parent->pn_po, pcn, &po); - if (rv) - return rv; - } else { - po.po_path = pcn->pcn_name; - po.po_len = pcn->pcn_namelen; - } - - if (pu->pu_namemod) { - /* XXX: gcc complains if I do assignment */ - memcpy(&pcn_orig, pcn, sizeof(pcn_orig)); - rv = pu->pu_namemod(pu, &pn_parent->pn_po, pcn); - if (rv) - return rv; - } - - rv = pu->pu_pathbuild(pu, &pn_parent->pn_po, &po, 0, - &pcn->pcn_po_full); - puffs_path_buildhash(pu, &pcn->pcn_po_full); - - if (pu->pu_pathtransform) - pu->pu_pathfree(pu, &po); - - if (pu->pu_namemod && rv) - *pcn = pcn_orig; - - return rv; -} - -/* - * substitute all (child) patch prefixes. called from nodewalk, which - * in turn is called from rename - */ -void * -puffs_path_prefixadj(struct puffs_usermount *pu, struct puffs_node *pn, - void *arg) -{ - struct puffs_pathinfo *pi = arg; - struct puffs_pathobj localpo; - struct puffs_pathobj oldpo; - int rv; - - /* can't be a path prefix */ - if (pn->pn_po.po_len < pi->pi_old->po_len) - return NULL; - - if (pu->pu_pathcmp(pu, &pn->pn_po, pi->pi_old, pi->pi_old->po_len, 1)) - return NULL; - - /* otherwise we'd have two nodes with an equal path */ - assert(pn->pn_po.po_len > pi->pi_old->po_len); - - /* found a matching prefix */ - rv = pu->pu_pathbuild(pu, pi->pi_new, &pn->pn_po, - pi->pi_old->po_len, &localpo); - /* - * XXX: technically we shouldn't fail, but this is the only - * sensible thing to do here. If the buildpath routine fails, - * we will have paths in an inconsistent state. Should fix this, - * either by having two separate passes or by doing other tricks - * to make an invalid path with BUILDPATHS acceptable. - */ - if (rv != 0) - abort(); - - /* adjust hash sum */ - puffs_path_buildhash(pu, &localpo); - - /* out with the old and in with the new */ - oldpo = pn->pn_po; - pn->pn_po = localpo; - pu->pu_pathfree(pu, &oldpo); - - /* continue the walk */ - return NULL; -} - -/* - * called from nodewalk, checks for exact match - */ -void * -puffs_path_walkcmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg) -{ - struct puffs_pathobj *po = arg; - struct puffs_pathobj po2; - - if (po->po_len != PNPLEN(pn)) - return NULL; - - /* - * If hashing and the hash doesn't match, we know this is - * definitely not a match. Otherwise check for collisions. - */ - if (pu->pu_flags & PUFFS_FLAG_HASHPATH) - if (pn->pn_po.po_hash != po->po_hash) - return NULL; - - po2.po_path = PNPATH(pn); - po2.po_len = PNPLEN(pn); - - if (pu->pu_pathcmp(pu, po, &po2, PNPLEN(pn), 0) == 0) - return pn; - return NULL; -} - -/* - * Hash sum building routine. Use string hash if the buildpath routine - * is the standard one, otherwise use binary hashes. A bit whimsical - * way to choose the routine, but the binary works for strings also, - * so don't sweat it. - */ -void -puffs_path_buildhash(struct puffs_usermount *pu, struct puffs_pathobj *po) -{ - - if ((pu->pu_flags & PUFFS_FLAG_HASHPATH) == 0) - return; - - if (pu->pu_pathbuild == puffs_stdpath_buildpath) - po->po_hash = hash32_strn(po->po_path, po->po_len, - HASH32_STR_INIT); - else - po->po_hash = hash32_buf(po->po_path, po->po_len, - HASH32_BUF_INIT); -} - -/* - * Routines provided to file systems which consider a path a tuple of - * strings and / the component separator. - */ - -/*ARGSUSED*/ -int -puffs_stdpath_cmppath(struct puffs_usermount *pu, struct puffs_pathobj *c1, - struct puffs_pathobj *c2, size_t clen, int checkprefix) -{ - char *p; - int rv; - - rv = strncmp(c1->po_path, c2->po_path, clen); - if (rv) - return 1; - - if (checkprefix == 0) - return 0; - - /* sanity for next step */ - if (!(c1->po_len > c2->po_len)) - return 1; - - /* check if it's really a complete path prefix */ - p = c1->po_path; - if ((*(p + clen)) != '/') - return 1; - - return 0; -} - -/*ARGSUSED*/ -int -puffs_stdpath_buildpath(struct puffs_usermount *pu, - const struct puffs_pathobj *po_pre, const struct puffs_pathobj *po_comp, - size_t offset, struct puffs_pathobj *newpath) -{ - char *path, *pcomp; - size_t plen, complen; - size_t prelen; - int isdotdot; - - complen = po_comp->po_len - offset; - - /* seek to correct place & remove all leading '/' from component */ - pcomp = po_comp->po_path; - pcomp += offset; - while (*pcomp == '/') { - pcomp++; - complen--; - } - - /* todotdot or nottodotdot */ - if (complen == 2 && strcmp(pcomp, "..") == 0) - isdotdot = 1; - else - isdotdot = 0; - - /* - * Strip trailing components from the preceending component. - * This is an issue only for the root node, which we might want - * to be at path "/" for some file systems. - */ - prelen = po_pre->po_len; - while (prelen > 0 && *((char *)po_pre->po_path + (prelen-1)) == '/') { - assert(isdotdot == 0); - prelen--; - } - - if (isdotdot) { - char *slash; /* sweet char of mine */ - - slash = strrchr(po_pre->po_path, '/'); - assert(slash != NULL); - - plen = slash - (char *)po_pre->po_path; - - /* - * As the converse to not stripping the initial "/" above, - * don't nuke it here either. - */ - if (plen == 0) - plen++; - - path = malloc(plen + 1); - if (path == NULL) - return errno; - - strlcpy(path, po_pre->po_path, plen+1); - } else { - /* + '/' + '\0' */ - plen = prelen + 1 + complen; - path = malloc(plen + 1); - if (path == NULL) - return errno; - - strlcpy(path, po_pre->po_path, prelen+1); - strcat(path, "/"); - strncat(path, pcomp, complen); - } - - newpath->po_path = path; - newpath->po_len = plen; - - return 0; -} - -/*ARGSUSED*/ -void -puffs_stdpath_freepath(struct puffs_usermount *pu, struct puffs_pathobj *po) -{ - - free(po->po_path); -} diff --git a/lib/libpuffs/pnode.c b/lib/libpuffs/pnode.c deleted file mode 100644 index 81441eb09..000000000 --- a/lib/libpuffs/pnode.c +++ /dev/null @@ -1,216 +0,0 @@ -/* $NetBSD: pnode.c,v 1.13 2012/08/16 09:25:43 manu Exp $ */ - -/* - * Copyright (c) 2006 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: pnode.c,v 1.13 2012/08/16 09:25:43 manu Exp $"); -#endif /* !lint */ - -#include - -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -/* - * Well, you're probably wondering why this isn't optimized. - * The reason is simple: my available time is not optimized for - * size ... so please be patient ;) - */ -struct puffs_node * -puffs_pn_new(struct puffs_usermount *pu, void *privdata) -{ - struct puffs_node *pn; - - pn = calloc(1, sizeof(struct puffs_node)); - if (pn == NULL) - return NULL; - - pn->pn_data = privdata; - pn->pn_mnt = pu; - puffs_vattr_null(&pn->pn_va); - - LIST_INSERT_HEAD(&pu->pu_pnodelst, pn, pn_entries); - - pu->pu_flags |= PUFFS_FLAG_PNCOOKIE; - - return pn; -} - -void -puffs_pn_remove(struct puffs_node *pn) -{ - - LIST_REMOVE(pn, pn_entries); - pn->pn_flags |= PUFFS_NODE_REMOVED; -#if defined(__minix) - if (pn->pn_count != 0) { - struct puffs_usermount *pu = pn->pn_mnt; - assert(pu != NULL); - - /* XXX FS removes this pn from the list to prevent further - * lookups from finding node after remove/rm/rename op. - * But VFS still uses it, i.e. pnode is still open, and - * will put it later. Keep it in separate list to do reclaim - * in fs_put(). - */ - LIST_INSERT_HEAD(&pu->pu_pnode_removed_lst, pn, pn_entries); - } -#endif /* defined(__minix) */ -} - -void -puffs_pn_put(struct puffs_node *pn) -{ - struct puffs_usermount *pu = pn->pn_mnt; - - pu->pu_pathfree(pu, &pn->pn_po); - if ((pn->pn_flags & PUFFS_NODE_REMOVED) == 0) - LIST_REMOVE(pn, pn_entries); - free(pn); -} - -/* walk list, rv can be used either to halt or to return a value */ -void * -puffs_pn_nodewalk(struct puffs_usermount *pu, puffs_nodewalk_fn fn, void *arg) -{ - struct puffs_node *pn_cur, *pn_next; - void *rv; - - pn_cur = LIST_FIRST(&pu->pu_pnodelst); - while (pn_cur) { - pn_next = LIST_NEXT(pn_cur, pn_entries); - rv = fn(pu, pn_cur, arg); - if (rv) - return rv; - pn_cur = pn_next; - } - - return NULL; -} - -struct vattr * -puffs_pn_getvap(struct puffs_node *pn) -{ - - return &pn->pn_va; -} - -void * -puffs_pn_getpriv(struct puffs_node *pn) -{ - - return pn->pn_data; -} - -void -puffs_pn_setpriv(struct puffs_node *pn, void *priv) -{ - - pn->pn_data = priv; -} - -struct puffs_pathobj * -puffs_pn_getpo(struct puffs_node *pn) -{ - - return &pn->pn_po; -} - -struct puffs_usermount * -puffs_pn_getmnt(struct puffs_node *pn) -{ - - return pn->pn_mnt; -} - -/* convenience / shortcut */ -void * -puffs_pn_getmntspecific(struct puffs_node *pn) -{ - - return pn->pn_mnt->pu_privdata; -} - -/* - * newnode parameters - */ -void -puffs_newinfo_setcookie(struct puffs_newinfo *pni, puffs_cookie_t cookie) -{ - - *pni->pni_cookie = cookie; -} - -void -puffs_newinfo_setvtype(struct puffs_newinfo *pni, enum vtype vt) -{ - - *pni->pni_vtype = vt; -} - -void -puffs_newinfo_setsize(struct puffs_newinfo *pni, voff_t size) -{ - - *pni->pni_size = size; -} - -void -puffs_newinfo_setrdev(struct puffs_newinfo *pni, dev_t rdev) -{ - - *pni->pni_rdev = rdev; -} - -void -puffs_newinfo_setva(struct puffs_newinfo *pni, struct vattr *va) -{ - - (void)memcpy(pni->pni_va, va, sizeof(struct vattr)); -} - -void -puffs_newinfo_setvattl(struct puffs_newinfo *pni, struct timespec *va_ttl) -{ - - pni->pni_va_ttl->tv_sec = va_ttl->tv_sec; - pni->pni_va_ttl->tv_nsec = va_ttl->tv_nsec; -} - -void -puffs_newinfo_setcnttl(struct puffs_newinfo *pni, struct timespec *cn_ttl) -{ - - pni->pni_cn_ttl->tv_sec = cn_ttl->tv_sec; - pni->pni_cn_ttl->tv_nsec = cn_ttl->tv_nsec; -} - diff --git a/lib/libpuffs/puffs.3 b/lib/libpuffs/puffs.3 deleted file mode 100644 index 534532e8c..000000000 --- a/lib/libpuffs/puffs.3 +++ /dev/null @@ -1,593 +0,0 @@ -.\" $NetBSD: puffs.3,v 1.61 2015/02/16 10:48:34 wiz Exp $ -.\" -.\" Copyright (c) 2006, 2007, 2008 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd February 15, 2015 -.Dt PUFFS 3 -.Os -.Sh NAME -.Nm puffs -.Nd Pass-to-Userspace Framework File System development interface -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft struct puffs_usermount * -.Fo puffs_init -.Fa "struct puffs_ops *pops" "const char *mntfromname" "const char *puffsname" -.Fa "void *private" "uint32_t flags" -.Fc -.Ft int -.Fo puffs_mount -.Fa "struct puffs_usermount *pu" "const char *dir" "int mntflags" -.Fa "puffs_cookie_t root_cookie" -.Fc -.Ft int -.Fn puffs_getselectable "struct puffs_usermount *pu" -.Ft int -.Fn puffs_setblockingmode "struct puffs_usermount *pu" "int mode" -.Ft int -.Fn puffs_getstate "struct puffs_usermount *pu" -.Ft int -.Fn puffs_setstacksize "struct puffs_usermount *pu" "size_t stacksize" -.Ft void -.Fn puffs_setroot "struct puffs_usermount *pu" "struct puffs_node *node" -.Ft void -.Fo puffs_setrootinfo -.Fa "struct puffs_usermount *pu" "enum vtype vt" "vsize_t vsize" "dev_t rdev" -.Fc -.Ft struct puffs_node * -.Fn puffs_getroot "struct puffs_usermount *pu" -.Ft void * -.Fn puffs_getspecific "struct puffs_usermount *pu" -.Ft void -.Fn puffs_setspecific "struct puffs_usermount *pu" "void *private" -.Ft void -.Fn puffs_setmaxreqlen "struct puffs_usermount *pu" "size_t maxreqlen" -.Ft size_t -.Fn puffs_getmaxreqlen "struct puffs_usermount *pu" -.Ft void -.Fn puffs_setfhsize "struct puffs_usermount *pu" "size_t fhsize" "int flags" -.Ft void -.Fn puffs_setncookiehash "struct puffs_usermount *pu" "int nhashes" -.Ft void -.Fn puffs_ml_loop_fn "struct puffs_usermount *pu" -.Ft void -.Fn puffs_ml_setloopfn "struct puffs_usermount *pu" "puffs_ml_loop_fn lfn" -.Ft void -.Fn puffs_ml_settimeout "struct puffs_usermount *pu" "struct timespec *ts" -.Ft int -.Fn puffs_daemon "struct puffs_usermount *pu" "int nochdir" "int noclose" -.Ft int -.Fn puffs_mainloop "struct puffs_usermount *pu" -.Ft int -.Fn puffs_unmountonsignal "int sig" "bool ignoresig" -.Ft int -.Fo puffs_dispatch_create -.Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pb" -.Fa "struct puffs_cc **pccp" -.Fc -.Ft int -.Fn puffs_dispatch_exec "struct puffs_cc *pcc" "struct puffs_framebuf **pbp" -.Sh DESCRIPTION -.Nm -provides a framework for creating file systems as userspace servers. -Operations are transported from the kernel virtual file system layer -to the concrete implementation behind -.Nm , -where they are processed and results are sent back to the kernel. -.Pp -It is possible to use -.Nm -in two different ways. -Calling -.Fn puffs_mainloop -takes execution context away from the caller and automatically handles -all requests by using the callbacks. -By using -.Xr puffs_framebuf 3 -in conjuction with -.Fn puffs_mainloop , -it is possible to handle I/O to and from file descriptors. -This is suited e.g. for distributed file servers. -.Ss Library operation -Operations on the library always require a pointer to the opaque context -identifier, -.Va struct puffs_usermount . -It is obtained by calling -.Fn puffs_init . -.Pp -.Nm -operates using operation callbacks. -They can be initialized using the macro -.Fn PUFFSOP_SET pops fsname type opname , -which will initialize the operation -.Fn puffs_type_opname -in -.Fa pops -to -.Fn fsname_type_opname . -All operations are initialized to a default state with the call -.Fn PUFFSOP_INIT pops . -All of the VFS routines are mandatory, but all of the node operations -with the exception of -.Fn puffs_node_lookup -are optional. -However, leaving operations blank will naturally have an effect on the -features available from the file system implementation. -.Bl -tag -width xxxx -.It Fn puffs_init pops mntfromname puffsname private flags -Initializes the library context. -.Ar pops -specifies the callback operations vector. -.Ar mntfromname -is device the file system is mounted from. -This can be for example a block device such as -.Pa /dev/wd0a -or, if the file system is pseudo file system, the -.Nm -device name can be given by -.Dv _PATH_PUFFS . -This value is used for example in the first column of the output of -.Xr mount 8 -and -.Xr df 1 . -.Ar puffsname -is the file system type. -It will always be prepended with the string "puffs|". -If possible, file server binaries should be named using the format -"mount_myfsnamehere" and this value should equal "myfsnamehere". -A file system specific context pointer can optionally be given in -.Ar private . -This can be retrieved by -.Fn puffs_getspecific . -Flags for -.Nm -can be given via -.Fa pflags . -Currently the following flags are supported: -.Bl -tag -width "XPUFFS_KFLAG_LOOKUP_FULLPNBUF" -.It Dv PUFFS_KFLAG_NOCACHE_NAME -Do not enter pathname components into the name cache. -This means that every time the kernel does a lookup for a -componentname, the file server will be consulted. -.It Dv PUFFS_KFLAG_NOCACHE_PAGE -Do not use the page cache. -This means that all reads and writes to regular file are -propagated to the file server for handling. -This option makes a difference only for regular files. -.It Dv PUFFS_KFLAG_NOCACHE -An alias for both -.Dv PUFFS_KFLAG_NOCACHE_NAME -and -.Dv PUFFS_KFLAG_NOCACHE_PAGE . -.It Dv PUFFS_KFLAG_ALLOPS -This flag requests that all operations are sent to userspace. -Normally the kernel shortcircuits unimplemented operations. -This flag is mostly useful for debugging purposes. -.It Dv PUFFS_KFLAG_WTCACHE -Set the file system cache behavior as write-through. -This means that all writes are immediately issued to the file server -instead of being flushed in file system sync. -This is useful especially for distributed file systems. -.It Dv PUFFS_KFLAG_IAONDEMAND -Issue inactive only on demand. -If a file server defines the inactive method, call it only if the file -server has explicitly requested that inactive be called for the -node in question. -Once inactive has been called for a node, it will not be called -again unless the request to call inactive is reissued by the file server. -See -.Fn puffs_setback -in -.Xr puffs_ops 3 -for more information. -.It Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF -This flag affects only the parameter -.Ar pcn to -.Fn puffs_node_lookup . -If this flag is not given, only the next pathname component under -lookup is found from -.Ar pcn-\*[Gt]pcn_name . -If this flag is given, the full path the kernel was -asked to resolve can be found from there. -.It Dv PUFFS_FLAG_BUILDPATH -The framework will build a complete path name, which is supplied -with each operation and can be found from the -.Va pcn_po_full.po_path -field in a -.Vt struct puffs_cn . -The option assumes that the framework can map a cookie to a -.Vt struct puffs_node . -See -.Sx Cookies -for more information on cookie mapping. -See -.Xr puffs_path 3 -for more information on library calls involving paths. -.It Dv PUFFS_FLAG_HASHPATH -Calculate a hash of the path into the path object field -.Va po_hash . -This hash value is used by -.Fn puffs_path_walkcmp -to avoid doing a full comparison for every path equal in length to -the one searched for. -Especially if the file system uses the abovementioned function, it -is a good idea to define this flag. -.It Dv PUFFS_FLAG_PNCOOKIE -Tell puffs that cookies map to -.Vt struct pnode . -This is automagically set if -.Fn puffs_pn_new -is called. -.It Dv PUFFS_KFLAG_CACHE_FS_TTL -Enforce name and attribute caches based on file system-supplied TTL. -In lookup, create, mknod, mkdir, and symlink, the file system must -update the node attributes, their TTL, and the node name TTL through -.Fn puffs_newinfo_setva , -.Fn puffs_newinfo_setvattl , -and -.Fn puffs_newinfo_setcnttl . -.Pp -Additionally, -.Fn puffs_node_getattr_ttl -and -.Fn puffs_node_setattr_ttl -will be called instead of -.Fn puffs_node_getattr -and -.Fn puffs_node_setattr . -.It Dv PUFFS_KFLAG_CACHE_DOTDOT -Never send lookups for -.Dq .. -to the file system. -Parent vnodes are all kept active until their children are reclaimed. -.It Dv PUFFS_KFLAG_NOFLUSH_META -Do not send metadata cache flushes for time and size to the file system, -which should take care of updating the values on its own. -.It Dv PUFFS_FLAG_OPDUMP -This option makes the framework dump a textual representation of -each operation before executing it. -It is useful for debugging purposes. -.El -.El -.Pp -The following functions can be used to query or modify the global -state of the file system. -Note, that all calls are not available at all times. -.Bl -tag -width xxxx -.It Fn puffs_getselectable "pu" -Returns a handle to do I/O multiplexing with: -.Xr select 2 , -.Xr poll 2 , -and -.Xr kqueue 2 -are all examples of acceptable operations. -.It Fn puffs_setblockingmode "pu" "mode" -Sets the file system upstream access to blocking or non-blocking mode. -Acceptable values for the argument are -.Dv PUFFSDEV_BLOCK -and -.Dv PUFFSDEV_NONBLOCK . -.Pp -This routine can be called only after calling -.Fn puffs_mount . -.It Fn puffs_getstate "pu" -Returns the state of the file system. -It is maintained by the framework and is mostly useful for the framework -itself. -Possible values are -.Dv PUFFS_STATE_BEFOREMOUNT , -.Dv PUFFS_STATE_RUNNING , -.Dv PUFFS_STATE_UNMOUNTING -and -.Dv PUFFS_STATE_UNMOUNTED . -.It Fn puffs_setstacksize "pu" "stacksize" -Sets the stack size used when running callbacks. -The default is -.Dv PUFFS_STACKSIZE_DEFAULT -bytes of stack space per request. -The minimum stacksize is architecture-dependent and can be specified -by using the opaque constant -.Dv PUFFS_STACKSIZE_MIN . -.It Fn puffs_setroot "pu" "node" -Sets the root node of mount -.Fa pu -to -.Fa "node" . -Setting the root node is currently required only if the path -framework is used, see -.Xr puffs_path 3 . -.It Fn puffs_setrootinfo pu vt vsize rdev -The default root node is a directory. -In case the file system wants something different, it can call this -function and set the type, size and possible device type to whatever -it wants. -This routine is independent of -.Fn puffs_setroot . -.It Fn puffs_getroot "pu" -Returns the root node set earlier. -.It Fn puffs_getspecific "pu" -Returns the -.Fa private -argument of -.Fn puffs_init . -.It Fn puffs_setspecific "pu" "private" -Can be used to set the specific data after the call to -.Fn puffs_init . -.It Fn puffs_setmaxreqlen "pu" "maxreqlen" -In case the file system desires a maximum buffer length different from -the default, the amount -.Fa maxreqlen -will be requested from the kernel when the file system is mounted. -.Pp -It is legal to call this function only between -.Fn puffs_init -and -.Fn puffs_mount . -.Pp -.Em NOTE -This does not currently work. -.It Fn puffs_getmaxreqlen "pu" -Returns the maximum request length the kernel will need for a single -request. -.Pp -.Em NOTE -This does not currently work. -.It Fn puffs_setfhsize "pu" "fhsize" "flags" -Sets the desired file handle size. -This must be called if the file system wishes to support NFS exporting -file systems of the -.Fn fh* -family of function calls. -.Pp -In case all nodes in the file system produce the same length file handle, -it must be supplied as -.Fa fhsize . -In this case, the file system may ignore the length parameters in the -file handle callback routines, as the kernel will always pass the -correct length buffer. -However, if the file handle size varies according to file, the argument -.Fa fhsize -defines the maximum size of a file handle for the file system. -In this case the file system must take care of the handle lengths by -itself in the file handle callbacks, see -.Xr puffs_ops 3 -for more information. -Also, the flag -.Dv PUFFS_FHFLAG_DYNAMIC -must be provided in the argument -.Fa flags . -.Pp -In case the file system wants to sanity check its file handle lengths -for the limits of NFS, it can supply -.Dv PUFFS_FHFLAG_NFSV2 -and -.Dv PUFFS_FHFLAG_NFSV3 -in the -.Fa flags -parameter. -It is especially important to note that these are not directly the -limits specified by the protocols, as the kernel uses some bytes from -the buffer space. -In case the file handles are too large, mount will return an error. -.Pp -It is legal to call this function only between -.Fn puffs_init -and -.Fn puffs_mount . -.It Fn puffs_setncookiehash "pu" "ncookiehash" -The parameter -.Fa ncookiehash -controls the amount of hash buckets the kernel has for reverse lookups -from cookie to vnode. -Technically the default is enough, but a memory/time tradeoff can be -made by increasing this for file systems which know they will have -very many active files. -.Pp -It is legal to call this function only between -.Fn puffs_init -and -.Fn puffs_mount . -.El -.Pp -After the correct setup for the library has been established and the -backend has been initialized the file system is made operational by calling -.Fn puffs_mount . -After this function returns the file system should start processing requests. -.Bl -tag -width xxxx -.It Fn puffs_mount pu dir mntflags root_cookie -.Ar pu -is the library context pointer from -.Fn puffs_init . -The argument -.Fa dir -signifies the mount point and -.Fa mntflags -is the flagset given to -.Xr mount 2 . -The value -.Ar root_cookie -will be used as the cookie for the file system root node. -.El -.Ss Using the built-in eventloop -.Bl -tag -width xxxx -.It Fn puffs_ml_loop_fn pu -Loop function signature. -.It Fn puffs_ml_setloopfn pu lfn -Set loop function to -.Ar lfn . -This function is called once each time the event loop loops. -It is not a well-defined interval, but it can be made fairly regular -by setting the loop timeout by -.Fn puffs_ml_settimeout . -.It Fn puffs_ml_settimeout pu ts -Sets the loop timeout to -.Ar ts -or disables it if -.Ar ts -is -.Dv NULL . -This can be used to roughly control how often the loop callback -.Fn lfn -is called -.It Fn puffs_daemon pu nochdir noclose -Detach from the console like -.Fn daemon 3 . -This call synchronizes with -.Fn puffs_mount -and the foreground process does not exit before the file system mount -call has returned from the kernel. -Since this routine internally calls fork, it has to be called -.Em before -.Fn puffs_mount . -.It Fn puffs_mainloop pu flags -Handle all requests automatically until the file system is unmounted. -It returns 0 if the file system was successfully unmounted or \-1 if it -was killed in action. -.Pp -In case -.Xr puffs_framebuf 3 -has been initialized, I/O from the relevant descriptors is processed -automatically by the eventloop. -.It Fn puffs_unmountonsignal signum ignoresig -Cause all file servers within the process to initiate unmount upon -receipt of signal -.Ar signum . -This works only for servers which call -.Fn puffs_mainloop -and must be called before any server within the process enters the mainloop. -The process signal handler is still called before starting the unmount -procedure. -The parameter -.Ar ignoresig -is provided as a convenience and tells if to install a signal handler -to ignore -.Ar sig -so that the process will not e.g. terminate based on the default action -before the file system unmount can be initiated. -.It Fn puffs_dispatch_create pu pb pccp -.It Fn puffs_dispatch_exec pcc pbp -In case the use of -.Fn puffs_mainloop -is not possible, requests may be dispatched manually. -However, as this is less efficient than using the mainloop, -it should never be the first preference. -.Pp -Calling -.Fn puffs_dispatch_create -creates a dispatch request. -The argument -.Ar pb -should contains a valid request and upon success -.Ar pccp -will contain a valid request context. -This context is passed to -.Fn puffs_dispatch_exec -to execute the request. -If the request yielded before completing, the routine returns 0, -otherwise 1. -When the routine completes, -.Ar pcc -is made invalid and a pointer to the processed buffer is placed in -.Ar pbp . -It is the responsibility of the caller to send the response (if -necessary) and destroy the buffer. -.Pp -See -.Xr puffs_cc 3 -and -.Xr puffs_framebuf 3 -for further information. -.El -.Ss Cookies -Every file (regular file, directory, device node, ...) instance is -attached to the kernel using a cookie. -A cookie should uniquely map to a file during its lifetime. -If file instances are kept in memory, a simple strategy is to use -the virtual address of the structure describing the file. -The cookie can be recycled when -.Fn puffs_node_reclaim -is called for a node. -.Pp -For some operations (such as building paths) the framework needs to map -the cookie to the framework-level structure describing a file, -.Vt struct puffs_node . -It is advisable to simply use the -.Vt struct puffs_node -address as a cookie and store file system specific data in the private -portion of -.Vt struct puffs_node . -The library assumes this by default. -If it is not desirable, the file system implementation can call -.Fn puffs_set_cookiemap -to provide an alternative cookie-to-node mapping function. -.Sh SEE ALSO -.Xr mount 2 , -.Xr puffs_cc 3 , -.Xr puffs_cred 3 , -.Xr puffs_flush 3 , -.Xr puffs_framebuf 3 , -.Xr puffs_node 3 , -.Xr puffs_ops 3 , -.Xr puffs_path 3 , -.Xr refuse 3 , -.Xr puffs 4 -.Rs -.%A Antti Kantee -.%D March 2007 -.%J Proceedings of AsiaBSDCon 2007 -.%P pp. 29-42 -.%T puffs - Pass-to-Userspace Framework File System -.Re -.Rs -.%A Antti Kantee -.%D September 2007 -.%I Helsinki University of Technology -.%R Tech Report TKK-TKO-B157 -.%T Using puffs for Implementing Client-Server Distributed File Systems -.Re -.Rs -.%A Antti Kantee -.%A Alistair Crooks -.%D September 2007 -.%J EuroBSDCon 2007 -.%T ReFUSE: Userspace FUSE Reimplementation Using puffs -.Re -.Rs -.%A Antti Kantee -.%D March 2008 -.%J Proceedings of AsiaBSDCon 2008 -.%P pp. 55-70 -.%T Send and Receive of File System Protocols: Userspace Approach With puffs -.Re -.Sh HISTORY -An unsupported experimental version of -.Nm -first appeared in -.Nx 4.0 . -A stable version appeared in -.Nx 5.0 . -.Sh AUTHORS -.An Antti Kantee Aq Mt pooka@iki.fi diff --git a/lib/libpuffs/puffs.c b/lib/libpuffs/puffs.c deleted file mode 100644 index c8cb28693..000000000 --- a/lib/libpuffs/puffs.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* $NetBSD: puffs.c,v 1.120 2015/06/17 00:15:26 christos Exp $ */ - -/* - * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Google Summer of Code program and the Ulla Tuominen Foundation. - * The Google SoC project was mentored by Bill Studenmund. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: puffs.c,v 1.120 2015/06/17 00:15:26 christos Exp $"); -#endif /* !lint */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#if !defined(__minix) -#include -#endif /* !defined(__minix) */ -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -/* Most file systems want this for opts, so just give it to them */ -const struct mntopt puffsmopts[] = { - MOPT_STDOPTS, - PUFFSMOPT_STD, - MOPT_NULL, -}; - -#if !defined(__minix) -pthread_mutex_t pu_lock = PTHREAD_MUTEX_INITIALIZER; -#endif /* !defined(__minix) */ - -#define FILLOP(lower, upper) \ -do { \ - if (pops->puffs_node_##lower) \ - opmask[PUFFS_VN_##upper] = 1; \ -} while (/*CONSTCOND*/0) -static void -fillvnopmask(struct puffs_ops *pops, struct puffs_kargs *pa) -{ - uint8_t *opmask = pa->pa_vnopmask; - - memset(opmask, 0, sizeof(pa->pa_vnopmask)); - - FILLOP(create, CREATE); - FILLOP(mknod, MKNOD); - FILLOP(open, OPEN); - FILLOP(close, CLOSE); - FILLOP(access, ACCESS); - FILLOP(getattr, GETATTR); - FILLOP(setattr, SETATTR); - FILLOP(poll, POLL); - FILLOP(mmap, MMAP); - FILLOP(fsync, FSYNC); - FILLOP(seek, SEEK); - FILLOP(remove, REMOVE); - FILLOP(link, LINK); - FILLOP(rename, RENAME); - FILLOP(mkdir, MKDIR); - FILLOP(rmdir, RMDIR); - FILLOP(symlink, SYMLINK); - FILLOP(readdir, READDIR); - FILLOP(readlink, READLINK); - FILLOP(reclaim, RECLAIM); - FILLOP(inactive, INACTIVE); - FILLOP(print, PRINT); - FILLOP(read, READ); - FILLOP(write, WRITE); - FILLOP(advlock, ADVLOCK); - FILLOP(abortop, ABORTOP); - FILLOP(pathconf, PATHCONF); - - FILLOP(getextattr, GETEXTATTR); - FILLOP(setextattr, SETEXTATTR); - FILLOP(listextattr, LISTEXTATTR); - FILLOP(deleteextattr, DELETEEXTATTR); - FILLOP(fallocate, FALLOCATE); - FILLOP(fdiscard, FDISCARD); -} -#undef FILLOP - -/* - * Go over all framev entries and write everything we can. This is - * mostly for the benefit of delivering "unmount" to the kernel. - */ -static void -finalpush(struct puffs_usermount *pu) -{ -#if !defined(__minix) - struct puffs_fctrl_io *fio; - - LIST_FOREACH(fio, &pu->pu_ios, fio_entries) { - if (fio->stat & FIO_WRGONE) - continue; - - puffs__framev_output(pu, fio->fctrl, fio); - } -#endif /* !defined(__minix) */ -} - -/*ARGSUSED*/ -void -puffs_kernerr_abort(struct puffs_usermount *pu, uint8_t type, - int error, const char *str, puffs_cookie_t cookie) -{ - -#if !defined(__minix) - warnx("abort: type %d, error %d, cookie %p (%s)", -#else - lpuffs_debug("abort: type %d, error %d, cookie %p (%s)\n", -#endif /* !defined(__minix) */ - type, error, cookie, str); - abort(); -} - -/*ARGSUSED*/ -void -puffs_kernerr_log(struct puffs_usermount *pu, uint8_t type, - int error, const char *str, puffs_cookie_t cookie) -{ - - syslog(LOG_WARNING, "kernel: type %d, error %d, cookie %p (%s)", - type, error, cookie, str); -} - -#if !defined(__minix) -int -puffs_getselectable(struct puffs_usermount *pu) -{ - - return pu->pu_fd; -} - -uint64_t -puffs__nextreq(struct puffs_usermount *pu) -{ - uint64_t rv; - - PU_LOCK(); - rv = pu->pu_nextreq++ | (uint64_t)1<<63; - PU_UNLOCK(); - - return rv; -} - -int -puffs_setblockingmode(struct puffs_usermount *pu, int mode) -{ - int rv, x; - - assert(puffs_getstate(pu) == PUFFS_STATE_RUNNING); - - if (mode != PUFFSDEV_BLOCK && mode != PUFFSDEV_NONBLOCK) { - errno = EINVAL; - return -1; - } - - x = mode; - rv = ioctl(pu->pu_fd, FIONBIO, &x); - - if (rv == 0) { - if (mode == PUFFSDEV_BLOCK) - pu->pu_state &= ~PU_ASYNCFD; - else - pu->pu_state |= PU_ASYNCFD; - } - - return rv; -} -#endif /* !defined(__minix) */ - -int -puffs_getstate(struct puffs_usermount *pu) -{ - - return pu->pu_state & PU_STATEMASK; -} - -void -puffs_setstacksize(struct puffs_usermount *pu, size_t ss) -{ - long psize, minsize; - int stackshift; - int bonus; - - assert(puffs_getstate(pu) == PUFFS_STATE_BEFOREMOUNT); - - psize = sysconf(_SC_PAGESIZE); - minsize = 4*psize; - if (ss < (size_t)minsize || ss == PUFFS_STACKSIZE_MIN) { - if (ss != PUFFS_STACKSIZE_MIN) -#if !defined(__minix) - warnx("%s: adjusting " "stacksize to minimum %ld", - __func__, minsize); -#endif /* !defined(__minix) */ - ss = 4*psize; - } - - stackshift = -1; - bonus = 0; - while (ss) { - if (ss & 0x1) - bonus++; - ss >>= 1; - stackshift++; - } - if (bonus > 1) { - stackshift++; -#if !defined(__minix) - warnx("%s: using next power of two: %d", __func__, - 1 << stackshift); -#endif /* !defined(__minix) */ - } - - pu->pu_cc_stackshift = stackshift; -} - -struct puffs_pathobj * -puffs_getrootpathobj(struct puffs_usermount *pu) -{ - struct puffs_node *pnr; - - pnr = pu->pu_pn_root; - if (pnr == NULL) { - errno = ENOENT; - return NULL; - } - - return &pnr->pn_po; -} - -void -puffs_setroot(struct puffs_usermount *pu, struct puffs_node *pn) -{ - - pu->pu_pn_root = pn; -} - -struct puffs_node * -puffs_getroot(struct puffs_usermount *pu) -{ - - return pu->pu_pn_root; -} - -void -puffs_setrootinfo(struct puffs_usermount *pu, enum vtype vt, - vsize_t vsize, dev_t rdev) -{ - struct puffs_kargs *pargs = pu->pu_kargp; - - if (puffs_getstate(pu) != PUFFS_STATE_BEFOREMOUNT) { - warnx("%s: call has effect only before mount", __func__); - return; - } - - pargs->pa_root_vtype = vt; - pargs->pa_root_vsize = vsize; - pargs->pa_root_rdev = rdev; -} - -void * -puffs_getspecific(struct puffs_usermount *pu) -{ - - return pu->pu_privdata; -} - -void -puffs_setspecific(struct puffs_usermount *pu, void *privdata) -{ - - pu->pu_privdata = privdata; -} - -void -puffs_setmntinfo(struct puffs_usermount *pu, - const char *mntfromname, const char *puffsname) -{ - struct puffs_kargs *pargs = pu->pu_kargp; - - (void)strlcpy(pargs->pa_mntfromname, mntfromname, - sizeof(pargs->pa_mntfromname)); - (void)strlcpy(pargs->pa_typename, puffsname, - sizeof(pargs->pa_typename)); -} - -size_t -puffs_getmaxreqlen(struct puffs_usermount *pu) -{ - - return pu->pu_maxreqlen; -} - -void -puffs_setmaxreqlen(struct puffs_usermount *pu, size_t reqlen) -{ - - if (puffs_getstate(pu) != PUFFS_STATE_BEFOREMOUNT) - warnx("%s: call has effect only before mount", __func__); - - pu->pu_kargp->pa_maxmsglen = reqlen; -} - -void -puffs_setfhsize(struct puffs_usermount *pu, size_t fhsize, int flags) -{ - - if (puffs_getstate(pu) != PUFFS_STATE_BEFOREMOUNT) - warnx("%s: call has effect only before mount", __func__); - - pu->pu_kargp->pa_fhsize = fhsize; - pu->pu_kargp->pa_fhflags = flags; -} - -void -puffs_setncookiehash(struct puffs_usermount *pu, int nhash) -{ - - if (puffs_getstate(pu) != PUFFS_STATE_BEFOREMOUNT) - warnx("%s: call has effect only before mount", __func__); - - pu->pu_kargp->pa_nhashbuckets = nhash; -} - -void -puffs_set_pathbuild(struct puffs_usermount *pu, pu_pathbuild_fn fn) -{ - - pu->pu_pathbuild = fn; -} - -void -puffs_set_pathtransform(struct puffs_usermount *pu, pu_pathtransform_fn fn) -{ - - pu->pu_pathtransform = fn; -} - -void -puffs_set_pathcmp(struct puffs_usermount *pu, pu_pathcmp_fn fn) -{ - - pu->pu_pathcmp = fn; -} - -void -puffs_set_pathfree(struct puffs_usermount *pu, pu_pathfree_fn fn) -{ - - pu->pu_pathfree = fn; -} - -void -puffs_set_namemod(struct puffs_usermount *pu, pu_namemod_fn fn) -{ - - pu->pu_namemod = fn; -} - -void -puffs_set_errnotify(struct puffs_usermount *pu, pu_errnotify_fn fn) -{ - - pu->pu_errnotify = fn; -} - -void -puffs_set_cmap(struct puffs_usermount *pu, pu_cmap_fn fn) -{ - - pu->pu_cmap = fn; -} - -void -puffs_ml_setloopfn(struct puffs_usermount *pu, puffs_ml_loop_fn lfn) -{ - - pu->pu_ml_lfn = lfn; -} - -void -puffs_ml_settimeout(struct puffs_usermount *pu, struct timespec *ts) -{ - - if (ts == NULL) { - pu->pu_ml_timep = NULL; - } else { - pu->pu_ml_timeout = *ts; - pu->pu_ml_timep = &pu->pu_ml_timeout; - } -} - -void -puffs_set_prepost(struct puffs_usermount *pu, - pu_prepost_fn pre, pu_prepost_fn pst) -{ - - pu->pu_oppre = pre; - pu->pu_oppost = pst; -} - -#if !defined(__minix) -void -puffs_setback(struct puffs_cc *pcc, int whatback) -{ - struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb); - - assert(PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN && ( - preq->preq_optype == PUFFS_VN_OPEN || - preq->preq_optype == PUFFS_VN_MMAP || - preq->preq_optype == PUFFS_VN_REMOVE || - preq->preq_optype == PUFFS_VN_RMDIR || - preq->preq_optype == PUFFS_VN_INACTIVE)); - - preq->preq_setbacks |= whatback & PUFFS_SETBACK_MASK; -} - -int -puffs_daemon(struct puffs_usermount *pu, int nochdir, int noclose) -{ - long int n; - int parent, value, fd; - - if (pipe(pu->pu_dpipe) == -1) - return -1; - - switch (fork()) { - case -1: - return -1; - case 0: - parent = 0; - break; - default: - parent = 1; - break; - } - pu->pu_state |= PU_PUFFSDAEMON; - - if (parent) { - close(pu->pu_dpipe[1]); - n = read(pu->pu_dpipe[0], &value, sizeof(int)); - if (n == -1) - err(1, "puffs_daemon"); - if (n != sizeof(value)) - errx(1, "puffs_daemon got %ld bytes", n); - if (value) { - errno = value; - err(1, "puffs_daemon"); - } - exit(0); - } else { - if (setsid() == -1) - goto fail; - - if (!nochdir) - chdir("/"); - - if (!noclose) { - fd = open(_PATH_DEVNULL, O_RDWR, 0); - if (fd == -1) - goto fail; - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - if (fd > STDERR_FILENO) - close(fd); - } - return 0; - } - - fail: - n = write(pu->pu_dpipe[1], &errno, sizeof(int)); - assert(n == 4); - return -1; -} -#endif /* !defined(__minix) */ - -static void -shutdaemon(struct puffs_usermount *pu, int error) -{ -#if !defined(__minix) - ssize_t n; - - n = write(pu->pu_dpipe[1], &error, sizeof(int)); - assert(n == 4); - close(pu->pu_dpipe[0]); - close(pu->pu_dpipe[1]); -#endif /* !defined(__minix) */ - pu->pu_state &= ~PU_PUFFSDAEMON; -} - -int -puffs_mount(struct puffs_usermount *pu, const char *dir, int mntflags, - puffs_cookie_t cookie) -{ -#if !defined(__minix) - int rv, fd, sverrno; - char *comfd; -#endif /* !defined(__minix) */ - - pu->pu_kargp->pa_root_cookie = cookie; - -#if !defined(__minix) - /* XXXkludgehere */ - /* kauth doesn't provide this service any longer */ - if (geteuid() != 0) - mntflags |= MNT_NOSUID | MNT_NODEV; - - /* - * Undocumented... Well, documented only here. - * - * This is used for imaginative purposes. If the env variable is - * set, puffs_mount() doesn't do the regular mount procedure. - * Rather, it crams the mount data down the comfd and sets comfd as - * the puffs descriptor. - * - * This shouldn't be used unless you can read my mind ( ... or write - * it, not to mention execute it, but that's starting to get silly). - */ - if ((comfd = getenv("PUFFS_COMFD")) != NULL) { - size_t len; - - if (sscanf(comfd, "%d", &pu->pu_fd) != 1) { - errno = EINVAL; - rv = -1; - goto out; - } - /* check that what we got at least resembles an fd */ - if (fcntl(pu->pu_fd, F_GETFL) == -1) { - rv = -1; - goto out; - } - -#define allwrite(buf, len) \ -do { \ - ssize_t al_rv; \ - al_rv = write(pu->pu_fd, buf, len); \ - if ((size_t)al_rv != len) { \ - if (al_rv != -1) \ - errno = EIO; \ - rv = -1; \ - goto out; \ - } \ -} while (/*CONSTCOND*/0) - len = strlen(dir)+1; - allwrite(&len, sizeof(len)); - allwrite(dir, len); - len = strlen(pu->pu_kargp->pa_mntfromname)+1; - allwrite(&len, sizeof(len)); - allwrite(pu->pu_kargp->pa_mntfromname, len); - allwrite(&mntflags, sizeof(mntflags)); - len = sizeof(*pu->pu_kargp); - allwrite(&len, sizeof(len)); - allwrite(pu->pu_kargp, sizeof(*pu->pu_kargp)); - allwrite(&pu->pu_flags, sizeof(pu->pu_flags)); -#undef allwrite - - rv = 0; - } else { - char rp[MAXPATHLEN]; - size_t rplen,dirlen; - - if (realpath(dir, rp) == NULL) { - rv = -1; - goto out; - } - - rplen = strlen(rp); - dirlen = strlen(dir); - if (strncmp(dir, rp, rplen) != 0 || - strspn(dir + rplen, "/") != dirlen - rplen) { - warnx("puffs_mount: \"%s\" is a relative path.", dir); - warnx("puffs_mount: using \"%s\" instead.", rp); - } - - fd = open(_PATH_PUFFS, O_RDWR); - if (fd == -1) { - warnx("puffs_mount: cannot open %s", _PATH_PUFFS); - rv = -1; - goto out; - } - if (fd <= 2) - warnx("puffs_mount: device fd %d (<= 2), sure this is " - "what you want?", fd); - - pu->pu_kargp->pa_fd = pu->pu_fd = fd; - if ((rv = mount(MOUNT_PUFFS, rp, mntflags, - pu->pu_kargp, sizeof(struct puffs_kargs))) == -1) - goto out; - } -#else - /* Process the already-received mount request. */ - if (!lpuffs_pump()) { - /* Not mounted? This should never happen.. */ - free(pu->pu_kargp); - pu->pu_kargp = NULL; - errno = EINVAL; - return -1; - } -#endif /* !defined(__minix) */ - - PU_SETSTATE(pu, PUFFS_STATE_RUNNING); - -#if !defined(__minix) - out: - if (rv != 0) - sverrno = errno; - else - sverrno = 0; - free(pu->pu_kargp); - pu->pu_kargp = NULL; - - if (pu->pu_state & PU_PUFFSDAEMON) - shutdaemon(pu, sverrno); - - errno = sverrno; - return rv; -#else - return 0; -#endif /* !defined(__minix) */ -} - -struct puffs_usermount * -puffs_init(struct puffs_ops *pops, const char *mntfromname, - const char *puffsname, void *priv, uint32_t pflags) -{ - struct puffs_usermount *pu; - struct puffs_kargs *pargs; - int sverrno; - - if (puffsname == PUFFS_DEFER) - puffsname = "n/a"; - if (mntfromname == PUFFS_DEFER) - mntfromname = "n/a"; - if (priv == PUFFS_DEFER) - priv = NULL; - - pu = malloc(sizeof(struct puffs_usermount)); - if (pu == NULL) - goto failfree; - memset(pu, 0, sizeof(struct puffs_usermount)); - - pargs = pu->pu_kargp = malloc(sizeof(struct puffs_kargs)); - if (pargs == NULL) - goto failfree; - memset(pargs, 0, sizeof(struct puffs_kargs)); - - pargs->pa_vers = PUFFSVERSION; - pargs->pa_flags = PUFFS_FLAG_KERN(pflags); - fillvnopmask(pops, pargs); - puffs_setmntinfo(pu, mntfromname, puffsname); - - puffs_zerostatvfs(&pargs->pa_svfsb); - pargs->pa_root_cookie = NULL; - pargs->pa_root_vtype = VDIR; - pargs->pa_root_vsize = 0; - pargs->pa_root_rdev = 0; - pargs->pa_maxmsglen = 0; - if (/*CONSTCOND*/ sizeof(time_t) == 4) - pargs->pa_time32 = 1; - else - pargs->pa_time32 = 0; - - pu->pu_flags = pflags; - pu->pu_ops = *pops; - free(pops); /* XXX */ - - pu->pu_privdata = priv; - pu->pu_cc_stackshift = PUFFS_CC_STACKSHIFT_DEFAULT; - LIST_INIT(&pu->pu_pnodelst); - LIST_INIT(&pu->pu_ios); - LIST_INIT(&pu->pu_ios_rmlist); - LIST_INIT(&pu->pu_ccmagazin); - TAILQ_INIT(&pu->pu_sched); - -#if !defined(__minix) - pu->pu_framectrl[PU_FRAMECTRL_FS].rfb = puffs__fsframe_read; - pu->pu_framectrl[PU_FRAMECTRL_FS].wfb = puffs__fsframe_write; - pu->pu_framectrl[PU_FRAMECTRL_FS].cmpfb = puffs__fsframe_cmp; - pu->pu_framectrl[PU_FRAMECTRL_FS].gotfb = puffs__fsframe_gotframe; - pu->pu_framectrl[PU_FRAMECTRL_FS].fdnotfn = puffs_framev_unmountonclose; -#endif /* !defined(__minix) */ - - /* defaults for some user-settable translation functions */ - pu->pu_cmap = NULL; /* identity translation */ - - pu->pu_pathbuild = puffs_stdpath_buildpath; - pu->pu_pathfree = puffs_stdpath_freepath; - pu->pu_pathcmp = puffs_stdpath_cmppath; - pu->pu_pathtransform = NULL; - pu->pu_namemod = NULL; - - pu->pu_errnotify = puffs_kernerr_log; - - PU_SETSTATE(pu, PUFFS_STATE_BEFOREMOUNT); - -#if defined(__minix) - /* Do the MINIX3-specific side of the initialization. */ - lpuffs_init(pu); -#endif /* defined(__minix) */ - - return pu; - - failfree: - /* can't unmount() from here for obvious reasons */ - sverrno = errno; - free(pu); - errno = sverrno; - return NULL; -} - -void -puffs_cancel(struct puffs_usermount *pu, int error) -{ - - assert(puffs_getstate(pu) < PUFFS_STATE_RUNNING); - shutdaemon(pu, error); - free(pu); -} - -/*ARGSUSED1*/ -int -puffs_exit(struct puffs_usermount *pu, int unused /* strict compat */) -{ -#if !defined(__minix) - struct puffs_framebuf *pb; - struct puffs_req *preq; - void *winp; - size_t winlen; - int sverrno; - - pb = puffs_framebuf_make(); - if (pb == NULL) { - errno = ENOMEM; - return -1; - } - - winlen = sizeof(struct puffs_req); - if (puffs_framebuf_getwindow(pb, 0, &winp, &winlen) == -1) { - sverrno = errno; - puffs_framebuf_destroy(pb); - errno = sverrno; - return -1; - } - preq = winp; - - preq->preq_buflen = sizeof(struct puffs_req); - preq->preq_opclass = PUFFSOP_UNMOUNT; - preq->preq_id = puffs__nextreq(pu); - - puffs_framev_enqueue_justsend(pu, puffs_getselectable(pu), pb, 1, 0); -#else - struct puffs_node *pn; - - lpuffs_debug("puffs_exit\n"); - - while ((pn = LIST_FIRST(&pu->pu_pnodelst)) != NULL) - puffs_pn_put(pn); - - while ((pn = LIST_FIRST(&pu->pu_pnode_removed_lst)) != NULL) - puffs_pn_put(pn); - - puffs__cc_exit(pu); - if (pu->pu_state & PU_HASKQ) - close(pu->pu_kq); - free(pu); -#endif /* !defined(__minix) */ - - return 0; -} - -#if !defined(__minix) -/* no sigset_t static intializer */ -static int sigs[NSIG] = { 0, }; -static int sigcatch = 0; - -int -puffs_unmountonsignal(int sig, bool sigignore) -{ - - if (sig < 0 || sig >= (int)NSIG) { - errno = EINVAL; - return -1; - } - if (sigignore) - if (signal(sig, SIG_IGN) == SIG_ERR) - return -1; - - if (!sigs[sig]) - sigcatch++; - sigs[sig] = 1; - - return 0; -} -#endif /* !defined(__minix) */ - -/* - * Actual mainloop. This is called from a context which can block. - * It is called either from puffs_mainloop (indirectly, via - * puffs_cc_continue() or from puffs_cc_yield()). - */ -void -puffs__theloop(struct puffs_cc *pcc) -{ - struct puffs_usermount *pu = pcc->pcc_pu; -#if !defined(__minix) - struct puffs_framectrl *pfctrl; - struct puffs_fctrl_io *fio; - struct kevent *curev; - size_t nchanges; - int ndone; -#endif /* !defined(__minix) */ - -#if !defined(__minix) - while (puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED) { -#else - do { -#endif /* !defined(__minix) */ - - /* - * Schedule existing requests. - */ - while ((pcc = TAILQ_FIRST(&pu->pu_sched)) != NULL) { - TAILQ_REMOVE(&pu->pu_sched, pcc, pcc_schedent); - puffs__goto(pcc); - } - - if (pu->pu_ml_lfn) - pu->pu_ml_lfn(pu); - -#if !defined(__minix) - /* XXX: can we still do these optimizations? */ -#if 0 - /* - * Do this here, because: - * a) loopfunc might generate some results - * b) it's still "after" event handling (except for round 1) - */ - if (puffs_req_putput(ppr) == -1) - goto out; - puffs_req_resetput(ppr); - - /* micro optimization: skip kevent syscall if possible */ - if (pu->pu_nfds == 1 && pu->pu_ml_timep == NULL - && (pu->pu_state & PU_ASYNCFD) == 0) { - pfctrl = XXX->fctrl; - puffs_framev_input(pu, pfctrl, XXX); - continue; - } -#endif - - /* else: do full processing */ - /* Don't bother worrying about O(n) for now */ - LIST_FOREACH(fio, &pu->pu_ios, fio_entries) { - if (fio->stat & FIO_WRGONE) - continue; - - pfctrl = fio->fctrl; - - /* - * Try to write out everything to avoid the - * need for enabling EVFILT_WRITE. The likely - * case is that we can fit everything into the - * socket buffer. - */ - puffs__framev_output(pu, pfctrl, fio); - } - - /* - * Build list of which to enable/disable in writecheck. - */ - nchanges = 0; - LIST_FOREACH(fio, &pu->pu_ios, fio_entries) { - if (fio->stat & FIO_WRGONE) - continue; - - /* en/disable write checks for kqueue as needed */ - assert((FIO_EN_WRITE(fio) && FIO_RM_WRITE(fio)) == 0); - if (FIO_EN_WRITE(fio)) { - EV_SET(&pu->pu_evs[nchanges], fio->io_fd, - EVFILT_WRITE, EV_ENABLE, 0, 0, - (uintptr_t)fio); - fio->stat |= FIO_WR; - nchanges++; - } - if (FIO_RM_WRITE(fio)) { - EV_SET(&pu->pu_evs[nchanges], fio->io_fd, - EVFILT_WRITE, EV_DISABLE, 0, 0, - (uintptr_t)fio); - fio->stat &= ~FIO_WR; - nchanges++; - } - } - - ndone = kevent(pu->pu_kq, pu->pu_evs, nchanges, - pu->pu_evs, pu->pu_nevs, pu->pu_ml_timep); - - if (ndone == -1) { - if (errno != EINTR) - break; - else - continue; - } - - /* uoptimize */ - if (ndone == 0) - continue; - - /* iterate over the results */ - for (curev = pu->pu_evs; ndone--; curev++) { - int what; - -#if 0 - /* get & possibly dispatch events from kernel */ - if (curev->ident == puffsfd) { - if (puffs_req_handle(pgr, ppr, 0) == -1) - goto out; - continue; - } -#endif - - fio = (void *)curev->udata; - if (__predict_true(fio)) - pfctrl = fio->fctrl; - else - pfctrl = NULL; - if (curev->flags & EV_ERROR) { - assert(curev->filter == EVFILT_WRITE); - fio->stat &= ~FIO_WR; - - /* XXX: how to know if it's a transient error */ - puffs__framev_writeclose(pu, fio, - (int)curev->data); - puffs__framev_notify(fio, PUFFS_FBIO_ERROR); - continue; - } - - what = 0; - if (curev->filter == EVFILT_READ) { - puffs__framev_input(pu, pfctrl, fio); - what |= PUFFS_FBIO_READ; - } - - else if (curev->filter == EVFILT_WRITE) { - puffs__framev_output(pu, pfctrl, fio); - what |= PUFFS_FBIO_WRITE; - } - - else if (__predict_false(curev->filter==EVFILT_SIGNAL)){ - if ((pu->pu_state & PU_DONEXIT) == 0) { - PU_SETSFLAG(pu, PU_DONEXIT); - puffs_exit(pu, 0); - } - } - if (what) - puffs__framev_notify(fio, what); - } - - /* - * Really free fd's now that we don't have references - * to them. - */ - while ((fio = LIST_FIRST(&pu->pu_ios_rmlist)) != NULL) { - LIST_REMOVE(fio, fio_entries); - free(fio); - } -#endif /* !defined(__minix) */ - } -#if defined(__minix) - while (lpuffs_pump()); -#endif /* defined(__minix) */ - - if (puffs__cc_restoremain(pu) == -1) - warn("cannot restore main context. impending doom"); -} -int -puffs_mainloop(struct puffs_usermount *pu) -{ -#if !defined(__minix) - struct puffs_fctrl_io *fio; -#endif /* !defined(__minix) */ - struct puffs_cc *pcc; -#if !defined(__minix) - struct kevent *curev; - size_t nevs; - int sverrno, i; -#else - int sverrno; -#endif /* !defined(__minix) */ - - assert(puffs_getstate(pu) >= PUFFS_STATE_RUNNING); - -#if !defined(__minix) - pu->pu_kq = kqueue(); - if (pu->pu_kq == -1) - goto out; -#endif /* !defined(__minix) */ - pu->pu_state |= PU_HASKQ; - -#if !defined(__minix) - puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK); - if (puffs__framev_addfd_ctrl(pu, puffs_getselectable(pu), - PUFFS_FBIO_READ | PUFFS_FBIO_WRITE, - &pu->pu_framectrl[PU_FRAMECTRL_FS]) == -1) - goto out; - - nevs = pu->pu_nevs + sigcatch; - curev = realloc(pu->pu_evs, nevs * sizeof(struct kevent)); - if (curev == NULL) - goto out; - pu->pu_evs = curev; - pu->pu_nevs = nevs; - - LIST_FOREACH(fio, &pu->pu_ios, fio_entries) { - EV_SET(curev, fio->io_fd, EVFILT_READ, EV_ADD, - 0, 0, (uintptr_t)fio); - curev++; - EV_SET(curev, fio->io_fd, EVFILT_WRITE, EV_ADD | EV_DISABLE, - 0, 0, (uintptr_t)fio); - curev++; - } - for (i = 0; i < NSIG; i++) { - if (sigs[i]) { - EV_SET(curev, i, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, - 0, 0, 0); - curev++; - } - } - assert(curev - pu->pu_evs == (ssize_t)pu->pu_nevs); - if (kevent(pu->pu_kq, pu->pu_evs, pu->pu_nevs, NULL, 0, NULL) == -1) - goto out; -#endif /* !defined(__minix) */ - - pu->pu_state |= PU_INLOOP; - - /* - * Create alternate execution context and jump to it. Note - * that we come "out" of savemain twice. Where we come out - * of it depends on the architecture. If the return address is - * stored on the stack, we jump out from puffs_cc_continue(), - * for a register return address from puffs__cc_savemain(). - * PU_MAINRESTORE makes sure we DTRT in both cases. - */ - if (puffs__cc_create(pu, puffs__theloop, &pcc) == -1) { - goto out; - } - -#if 0 - if (puffs__cc_savemain(pu) == -1) { - goto out; - } -#else - /* - * XXX - * puffs__cc_savemain() uses getcontext() and then returns. - * the caller (this function) may overwrite the stack frame - * of puffs__cc_savemain(), so when we call setcontext() later and - * return from puffs__cc_savemain() again, the return address or - * saved stack pointer can be garbage. - * avoid this by calling getcontext() directly here. - */ - extern int puffs_fakecc; - if (!puffs_fakecc) { - PU_CLRSFLAG(pu, PU_MAINRESTORE); - if (getcontext(&pu->pu_mainctx) == -1) { - goto out; - } - } -#endif - - if ((pu->pu_state & PU_MAINRESTORE) == 0) - puffs_cc_continue(pcc); - - finalpush(pu); - errno = 0; - - out: - /* store the real error for a while */ - sverrno = errno; - - errno = sverrno; - if (errno) - return -1; - else - return 0; -} diff --git a/lib/libpuffs/puffs.h b/lib/libpuffs/puffs.h deleted file mode 100644 index e752b1e83..000000000 --- a/lib/libpuffs/puffs.h +++ /dev/null @@ -1,737 +0,0 @@ -/* $NetBSD: puffs.h,v 1.126 2014/10/31 13:56:04 manu Exp $ */ - -/* - * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Google Summer of Code program and the Ulla Tuominen Foundation. - * The Google SoC project was mentored by Bill Studenmund. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _PUFFS_H_ -#define _PUFFS_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -/* forwards */ -struct puffs_cc; - -struct puffs_getreq; -struct puffs_cred; -struct puffs_newinfo; - -/* paths */ -struct puffs_pathobj { - void *po_path; - size_t po_len; - uint32_t po_hash; -}; - -/* for prefix rename */ -struct puffs_pathinfo { - struct puffs_pathobj *pi_old; - struct puffs_pathobj *pi_new; -}; - -/* describes one segment cached in the kernel */ -struct puffs_kcache { - off_t pkc_start; - off_t pkc_end; - - LIST_ENTRY(puffs_kcache) pkc_entries; -}; - -/* XXX: might disappear from here into a private header */ -struct puffs_node { - off_t pn_size; - int pn_flags; - int pn_nlookup; - struct vattr pn_va; - - void *pn_data; /* private data */ - - struct puffs_pathobj pn_po; /* PUFFS_FLAG_BUILDPATH */ - - struct puffs_usermount *pn_mnt; - LIST_ENTRY(puffs_node) pn_entries; - - LIST_HEAD(,puffs_kcache)pn_cacheinfo; /* PUFFS_KFLAG_CACHE */ -#if defined(__minix) - /* MINIX fields */ - char pn_mountpoint; /* true if mounted on */ - unsigned int pn_count; /* # times inode used */ -#endif /* defined(__minix) */ -}; -#define PUFFS_NODE_REMOVED 0x01 /* not on entry list */ - - -struct puffs_usermount; - -/* - * megaXXX: these are values from inside _KERNEL - * need to work on the translation for ALL the necessary values. - */ -#define PUFFS_VNOVAL (-1) - -#define PUFFS_IO_APPEND 0x020 -#define PUFFS_IO_NDELAY 0x100 - -#define PUFFS_VEXEC 01 -#define PUFFS_VWRITE 02 -#define PUFFS_VREAD 04 - -#define PUFFS_FSYNC_DATAONLY 0x0002 -#define PUFFS_FSYNC_CACHE 0x0100 - -/* - * xflags for setattr_ttl and write2 - */ -#define PUFFS_SETATTR_FAF 0x1 -#define PUFFS_WRITE_FAF 0x1 - -#define PUFFS_EXTATTR_LIST_LENPREFIX 1 -/* - * Magic constants - */ -#define PUFFS_CC_STACKSHIFT_DEFAULT 18 - -struct puffs_cn { - struct puffs_kcn *pcn_pkcnp; /* kernel input */ - struct puffs_cred *pcn_cred; /* cred used for lookup */ - - struct puffs_pathobj pcn_po_full; /* PUFFS_FLAG_BUILDPATH */ -}; -#define pcn_nameiop pcn_pkcnp->pkcn_nameiop -#define pcn_flags pcn_pkcnp->pkcn_flags -#define pcn_name pcn_pkcnp->pkcn_name -#define pcn_namelen pcn_pkcnp->pkcn_namelen -#define pcn_consume pcn_pkcnp->pkcn_consume - -/* - * Puffs options to mount - */ -/* kernel */ -#define PUFFSMOPT_NAMECACHE { "namecache", 1, PUFFS_KFLAG_NOCACHE_NAME, 1 } -#define PUFFSMOPT_PAGECACHE { "pagecache", 1, PUFFS_KFLAG_NOCACHE_PAGE, 1 } -#define PUFFSMOPT_ATTRCACHE { "attrcache", 1, PUFFS_KFLAG_NOCACHE_ATTR, 1 } -#define PUFFSMOPT_CACHE { "cache", 1, PUFFS_KFLAG_NOCACHE, 1 } -#define PUFFSMOPT_ALLOPS { "allops", 0, PUFFS_KFLAG_ALLOPS, 1 } - -/* libpuffs */ -#define PUFFSMOPT_DUMP { "dump", 0, PUFFS_FLAG_OPDUMP, 1 } - -#define PUFFSMOPT_STD \ - PUFFSMOPT_NAMECACHE, \ - PUFFSMOPT_PAGECACHE, \ - PUFFSMOPT_ATTRCACHE, \ - PUFFSMOPT_CACHE, \ - PUFFSMOPT_ALLOPS, \ - PUFFSMOPT_DUMP - -extern const struct mntopt puffsmopts[]; /* puffs.c */ - -/* callbacks for operations */ -struct puffs_ops { - int (*puffs_fs_unmount)(struct puffs_usermount *, int); - int (*puffs_fs_statvfs)(struct puffs_usermount *, struct statvfs *); - int (*puffs_fs_sync)(struct puffs_usermount *, int, - const struct puffs_cred *); - int (*puffs_fs_fhtonode)(struct puffs_usermount *, void *, size_t, - struct puffs_newinfo *); - int (*puffs_fs_nodetofh)(struct puffs_usermount *, puffs_cookie_t, - void *, size_t *); - int (*puffs_fs_extattrctl)(struct puffs_usermount *, int, - puffs_cookie_t, int, int, const char *); - - int (*puffs_node_lookup)(struct puffs_usermount *, - puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *); - int (*puffs_node_create)(struct puffs_usermount *, - puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, - const struct vattr *); - int (*puffs_node_mknod)(struct puffs_usermount *, - puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, - const struct vattr *); - int (*puffs_node_open)(struct puffs_usermount *, - puffs_cookie_t, int, const struct puffs_cred *); - int (*puffs_node_close)(struct puffs_usermount *, - puffs_cookie_t, int, const struct puffs_cred *); - int (*puffs_node_access)(struct puffs_usermount *, - puffs_cookie_t, int, const struct puffs_cred *); - int (*puffs_node_getattr)(struct puffs_usermount *, - puffs_cookie_t, struct vattr *, const struct puffs_cred *); - int (*puffs_node_setattr)(struct puffs_usermount *, - puffs_cookie_t, const struct vattr *, const struct puffs_cred *); - int (*puffs_node_poll)(struct puffs_usermount *, puffs_cookie_t, int *); - int (*puffs_node_mmap)(struct puffs_usermount *, - puffs_cookie_t, vm_prot_t, const struct puffs_cred *); - int (*puffs_node_fsync)(struct puffs_usermount *, - puffs_cookie_t, const struct puffs_cred *, int, off_t, off_t); - int (*puffs_node_seek)(struct puffs_usermount *, - puffs_cookie_t, off_t, off_t, const struct puffs_cred *); - int (*puffs_node_remove)(struct puffs_usermount *, - puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); - int (*puffs_node_link)(struct puffs_usermount *, - puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); - int (*puffs_node_rename)(struct puffs_usermount *, - puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *, - puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); - int (*puffs_node_mkdir)(struct puffs_usermount *, - puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, - const struct vattr *); - int (*puffs_node_rmdir)(struct puffs_usermount *, - puffs_cookie_t, puffs_cookie_t, const struct puffs_cn *); - int (*puffs_node_symlink)(struct puffs_usermount *, - puffs_cookie_t, struct puffs_newinfo *, const struct puffs_cn *, - const struct vattr *, - const char *); - int (*puffs_node_readdir)(struct puffs_usermount *, - puffs_cookie_t, struct dirent *, off_t *, size_t *, - const struct puffs_cred *, int *, off_t *, size_t *); - int (*puffs_node_readlink)(struct puffs_usermount *, - puffs_cookie_t, const struct puffs_cred *, char *, size_t *); - int (*puffs_node_reclaim)(struct puffs_usermount *, puffs_cookie_t); - int (*puffs_node_inactive)(struct puffs_usermount *, puffs_cookie_t); - int (*puffs_node_print)(struct puffs_usermount *, puffs_cookie_t); - int (*puffs_node_pathconf)(struct puffs_usermount *, - puffs_cookie_t, int, register_t *); - int (*puffs_node_advlock)(struct puffs_usermount *, - puffs_cookie_t, void *, int, struct flock *, int); - int (*puffs_node_read)(struct puffs_usermount *, puffs_cookie_t, - uint8_t *, off_t, size_t *, const struct puffs_cred *, int); - int (*puffs_node_write)(struct puffs_usermount *, puffs_cookie_t, - uint8_t *, off_t, size_t *, const struct puffs_cred *, int); - int (*puffs_node_abortop)(struct puffs_usermount *, puffs_cookie_t, - const struct puffs_cn *); - int (*puffs_node_getextattr)(struct puffs_usermount *, puffs_cookie_t, - int, const char *, size_t *, uint8_t *, size_t *, - const struct puffs_cred *); - int (*puffs_node_setextattr)(struct puffs_usermount *, puffs_cookie_t, - int, const char *, uint8_t *, size_t *, const struct puffs_cred *); - int (*puffs_node_listextattr)(struct puffs_usermount *, puffs_cookie_t, - int, size_t *, uint8_t *, size_t *, int, const struct puffs_cred *); - int (*puffs_node_deleteextattr)(struct puffs_usermount *, - puffs_cookie_t, int, const char *, const struct puffs_cred *); - int (*puffs_node_getattr_ttl)(struct puffs_usermount *, - puffs_cookie_t, struct vattr *, const struct puffs_cred *, - struct timespec *); - int (*puffs_node_setattr_ttl)(struct puffs_usermount *, - puffs_cookie_t, struct vattr *, const struct puffs_cred *, - struct timespec *, int); - int (*puffs_node_write2)(struct puffs_usermount *, puffs_cookie_t, - uint8_t *, off_t, size_t *, const struct puffs_cred *, int, int); - int (*puffs_node_reclaim2)(struct puffs_usermount *, - puffs_cookie_t, int); - int (*puffs_node_open2)(struct puffs_usermount *, - puffs_cookie_t, int, const struct puffs_cred *, int *); - int (*puffs_node_fallocate)(struct puffs_usermount *, - puffs_cookie_t, off_t, off_t); - int (*puffs_node_fdiscard)(struct puffs_usermount *, - puffs_cookie_t, off_t, off_t); - - void *puffs_ops_spare[26]; -}; - -typedef int (*pu_pathbuild_fn)(struct puffs_usermount *, - const struct puffs_pathobj *, - const struct puffs_pathobj *, size_t, - struct puffs_pathobj *); -typedef int (*pu_pathtransform_fn)(struct puffs_usermount *, - const struct puffs_pathobj *, - const struct puffs_cn *, - struct puffs_pathobj *); -typedef int (*pu_pathcmp_fn)(struct puffs_usermount *, struct puffs_pathobj *, - struct puffs_pathobj *, size_t, int); -typedef void (*pu_pathfree_fn)(struct puffs_usermount *, - struct puffs_pathobj *); -typedef int (*pu_namemod_fn)(struct puffs_usermount *, - struct puffs_pathobj *, struct puffs_cn *); - -typedef void (*pu_errnotify_fn)(struct puffs_usermount *, - uint8_t, int, const char *, puffs_cookie_t); - -typedef void (*pu_prepost_fn)(struct puffs_usermount *); - -typedef struct puffs_node *(*pu_cmap_fn)(struct puffs_usermount *, - puffs_cookie_t); - -enum { - PUFFS_STATE_BEFOREMOUNT, PUFFS_STATE_RUNNING, - PUFFS_STATE_UNMOUNTING, PUFFS_STATE_UNMOUNTED -}; - -#define PUFFS_FLAG_BUILDPATH 0x80000000 /* node paths in pnode */ -#define PUFFS_FLAG_OPDUMP 0x40000000 /* dump all operations */ -#define PUFFS_FLAG_HASHPATH 0x20000000 /* speedup: hash paths */ -#define PUFFS_FLAG_PNCOOKIE 0x10000000 /* cookies are pnodes */ -#define PUFFS_FLAG_MASK 0xf0000000 - -#define PUFFS_FLAG_KERN(a) ((a) & PUFFS_KFLAG_MASK) -#define PUFFS_FLAG_LIB(a) ((a) & PUFFS_FLAG_MASK) - -/* blocking mode argument */ -#define PUFFSDEV_BLOCK 0 -#define PUFFSDEV_NONBLOCK 1 - -#define PUFFS_STACKSIZE_DEFAULT (1<puffs_##fsornode##_##opname = fsname##_##fsornode##_##opname -#define PUFFSOP_SETFSNOP(ops, opname) \ - (ops)->puffs_fs_##opname = puffs_fsnop_##opname - -PUFFSOP_PROTOS(puffs_null) /* XXX */ - -#define PNPATH(pnode) ((pnode)->pn_po.po_path) -#define PNPLEN(pnode) ((pnode)->pn_po.po_len) -#define PCNPATH(pcnode) ((pcnode)->pcn_po_full.po_path) -#define PCNPLEN(pcnode) ((pcnode)->pcn_po_full.po_len) -#define PCNISDOTDOT(pcnode) \ - ((pcnode)->pcn_namelen == 2 && strcmp((pcnode)->pcn_name, "..") == 0) - -#define PUFFS_STORE_DCOOKIE(cp, ncp, off) \ -if (cp) { \ - *((cp)++) = off; \ - (*(ncp))++; \ -} - -/* mainloop */ -typedef void (*puffs_ml_loop_fn)(struct puffs_usermount *); - -/* framebuf stuff */ -struct puffs_framebuf; -typedef int (*puffs_framev_readframe_fn)(struct puffs_usermount *, - struct puffs_framebuf *, - int, int *); -typedef int (*puffs_framev_writeframe_fn)(struct puffs_usermount *, - struct puffs_framebuf *, - int, int *); -typedef int (*puffs_framev_cmpframe_fn)(struct puffs_usermount *, - struct puffs_framebuf *, - struct puffs_framebuf *, - int *); -typedef void (*puffs_framev_fdnotify_fn)(struct puffs_usermount *, int, int); -typedef void (*puffs_framev_gotframe_fn)(struct puffs_usermount *, - struct puffs_framebuf *); -typedef void (*puffs_framev_cb)(struct puffs_usermount *, - struct puffs_framebuf *, - void *, int); -#define PUFFS_FBIO_READ 0x01 -#define PUFFS_FBIO_WRITE 0x02 -#define PUFFS_FBIO_ERROR 0x04 - -#define PUFFS_FBQUEUE_URGENT 0x01 - - -__BEGIN_DECLS - -#define PUFFS_DEFER ((void *)-1) -struct puffs_usermount *puffs_init(struct puffs_ops *, const char *, - const char *, void *, uint32_t); -int puffs_mount(struct puffs_usermount *, const char *, int, void*); -int puffs_exit(struct puffs_usermount *, int); -void puffs_cancel(struct puffs_usermount *, int); -int puffs_mainloop(struct puffs_usermount *); -int puffs_daemon(struct puffs_usermount *, int, int); - -int puffs_unmountonsignal(int, bool); - - -int puffs_getselectable(struct puffs_usermount *); -int puffs_setblockingmode(struct puffs_usermount *, int); -int puffs_getstate(struct puffs_usermount *); -void puffs_setstacksize(struct puffs_usermount *, size_t); - -void puffs_ml_setloopfn(struct puffs_usermount *, puffs_ml_loop_fn); -void puffs_ml_settimeout(struct puffs_usermount *, struct timespec *); - -void puffs_setroot(struct puffs_usermount *, - struct puffs_node *); -struct puffs_node *puffs_getroot(struct puffs_usermount *); -void puffs_setrootinfo(struct puffs_usermount *, - enum vtype, vsize_t, dev_t); - -void *puffs_getspecific(struct puffs_usermount *); -void puffs_setspecific(struct puffs_usermount *, void *); -void puffs_setmaxreqlen(struct puffs_usermount *, size_t); -size_t puffs_getmaxreqlen(struct puffs_usermount *); -void puffs_setfhsize(struct puffs_usermount *, size_t, int); -void puffs_setmntinfo(struct puffs_usermount *, - const char *, const char *); - -void puffs_setncookiehash(struct puffs_usermount *, int); - -struct puffs_pathobj *puffs_getrootpathobj(struct puffs_usermount *); - -void puffs_setback(struct puffs_cc *, int); - -struct puffs_node *puffs_pn_new(struct puffs_usermount *, void *); -void puffs_pn_remove(struct puffs_node *); -void puffs_pn_put(struct puffs_node *); -struct vattr *puffs_pn_getvap(struct puffs_node *); -void * puffs_pn_getpriv(struct puffs_node *); -void puffs_pn_setpriv(struct puffs_node *, void *); -struct puffs_pathobj *puffs_pn_getpo(struct puffs_node *); -struct puffs_usermount *puffs_pn_getmnt(struct puffs_node *); -struct timespec *puffs_pn_getvattl(struct puffs_node *); -struct timespec *puffs_pn_getcnttl(struct puffs_node *); - -void puffs_newinfo_setcookie(struct puffs_newinfo *, puffs_cookie_t); -void puffs_newinfo_setvtype(struct puffs_newinfo *, enum vtype); -void puffs_newinfo_setsize(struct puffs_newinfo *, voff_t); -void puffs_newinfo_setrdev(struct puffs_newinfo *, dev_t); -void puffs_newinfo_setva(struct puffs_newinfo *, struct vattr *); -void puffs_newinfo_setvattl(struct puffs_newinfo *, struct timespec *); -void puffs_newinfo_setcnttl(struct puffs_newinfo *, struct timespec *); - -void *puffs_pn_getmntspecific(struct puffs_node *); - -typedef void * (*puffs_nodewalk_fn)(struct puffs_usermount *, - struct puffs_node *, void *); -void *puffs_pn_nodewalk(struct puffs_usermount *, - puffs_nodewalk_fn, void *); - -void puffs_setvattr(struct vattr *, const struct vattr *); -void puffs_vattr_null(struct vattr *); - -void puffs_null_setops(struct puffs_ops *); - -int puffs_dispatch_create(struct puffs_usermount *, - struct puffs_framebuf *, - struct puffs_cc **); -int puffs_dispatch_exec(struct puffs_cc *, - struct puffs_framebuf **); - -/* - * generic/dummy routines applicable for some file systems - */ -int puffs_fsnop_unmount(struct puffs_usermount *, int); -int puffs_fsnop_statvfs(struct puffs_usermount *, struct statvfs *); -void puffs_zerostatvfs(struct statvfs *); -int puffs_fsnop_sync(struct puffs_usermount *, int waitfor, - const struct puffs_cred *); - -int puffs_genfs_node_getattr(struct puffs_usermount *, puffs_cookie_t, - struct vattr *, const struct puffs_cred *); -int puffs_genfs_node_reclaim(struct puffs_usermount *, puffs_cookie_t); - -/* - * Subroutine stuff - */ - -int puffs_gendotdent(struct dirent **, ino_t, int, size_t *); -int puffs_nextdent(struct dirent **, const char *, ino_t, - uint8_t, size_t *); -int puffs_vtype2dt(enum vtype); -enum vtype puffs_mode2vt(mode_t); -void puffs_stat2vattr(struct vattr *va, const struct stat *); -mode_t puffs_addvtype2mode(mode_t, enum vtype); - - -/* - * credentials & permissions - */ - -/* Credential fetch */ -int puffs_cred_getuid(const struct puffs_cred *, uid_t *); -int puffs_cred_getgid(const struct puffs_cred *, gid_t *); -int puffs_cred_getgroups(const struct puffs_cred *, gid_t *, short *); - -/* Credential check */ -bool puffs_cred_isuid(const struct puffs_cred *, uid_t); -bool puffs_cred_hasgroup(const struct puffs_cred *, gid_t); -bool puffs_cred_isregular(const struct puffs_cred *); -bool puffs_cred_iskernel(const struct puffs_cred *); -bool puffs_cred_isfs(const struct puffs_cred *); -bool puffs_cred_isjuggernaut(const struct puffs_cred *); - -/* misc */ -int puffs_access(enum vtype, mode_t, uid_t, gid_t, mode_t, - const struct puffs_cred *); -int puffs_access_chown(uid_t, gid_t, uid_t, gid_t, - const struct puffs_cred *); -int puffs_access_chmod(uid_t, gid_t, enum vtype, mode_t, - const struct puffs_cred *); -int puffs_access_times(uid_t, gid_t, mode_t, int, - const struct puffs_cred *); - - -/* - * Call Context interfaces relevant for user. - */ - -void puffs_cc_yield(struct puffs_cc *); -void puffs_cc_continue(struct puffs_cc *); -void puffs_cc_schedule(struct puffs_cc *); -int puffs_cc_getcaller(struct puffs_cc *,pid_t *,lwpid_t *); -struct puffs_cc *puffs_cc_getcc(struct puffs_usermount *); - -/* - * Flushing / invalidation routines - */ - -int puffs_inval_namecache_dir(struct puffs_usermount *, puffs_cookie_t); -int puffs_inval_namecache_all(struct puffs_usermount *); - -int puffs_inval_pagecache_node(struct puffs_usermount *, puffs_cookie_t); -int puffs_inval_pagecache_node_range(struct puffs_usermount *, - puffs_cookie_t, off_t, off_t); -int puffs_flush_pagecache_node(struct puffs_usermount *, puffs_cookie_t); -int puffs_flush_pagecache_node_range(struct puffs_usermount *, - puffs_cookie_t, off_t, off_t); - -/* - * Path constructicons - */ - -int puffs_stdpath_buildpath(struct puffs_usermount *, - const struct puffs_pathobj *, - const struct puffs_pathobj *, size_t, - struct puffs_pathobj *); -int puffs_stdpath_cmppath(struct puffs_usermount *, struct puffs_pathobj *, - struct puffs_pathobj *, size_t, int); -void puffs_stdpath_freepath(struct puffs_usermount *,struct puffs_pathobj *); - -void *puffs_path_walkcmp(struct puffs_usermount *, - struct puffs_node *, void *); -void *puffs_path_prefixadj(struct puffs_usermount *, - struct puffs_node *, void *); -int puffs_path_pcnbuild(struct puffs_usermount *, - struct puffs_cn *, void *); -void puffs_path_buildhash(struct puffs_usermount *, struct puffs_pathobj *); -void puffs_set_pathbuild(struct puffs_usermount *, pu_pathbuild_fn); void puffs_set_pathtransform(struct puffs_usermount *, pu_pathtransform_fn); -void puffs_set_pathcmp(struct puffs_usermount *, pu_pathcmp_fn); -void puffs_set_pathfree(struct puffs_usermount *, pu_pathfree_fn); -void puffs_set_namemod(struct puffs_usermount *, pu_namemod_fn); - -void puffs_set_errnotify(struct puffs_usermount *, pu_errnotify_fn); -void puffs_kernerr_log(struct puffs_usermount *, uint8_t, int, - const char *, puffs_cookie_t); -__dead void puffs_kernerr_abort(struct puffs_usermount *, uint8_t, int, - const char *, puffs_cookie_t); -void puffs_set_prepost(struct puffs_usermount *, - pu_prepost_fn, pu_prepost_fn); -void puffs_set_cmap(struct puffs_usermount *, pu_cmap_fn); - -/* - * Suspension - */ - -int puffs_fs_suspend(struct puffs_usermount *); - -/* - * Frame buffering - */ - -void puffs_framev_init(struct puffs_usermount *, - puffs_framev_readframe_fn, - puffs_framev_writeframe_fn, - puffs_framev_cmpframe_fn, - puffs_framev_gotframe_fn, - puffs_framev_fdnotify_fn); - -struct puffs_framebuf *puffs_framebuf_make(void); -void puffs_framebuf_destroy(struct puffs_framebuf *); -int puffs_framebuf_dup(struct puffs_framebuf *, - struct puffs_framebuf **); -void puffs_framebuf_recycle(struct puffs_framebuf *); -int puffs_framebuf_reserve_space(struct puffs_framebuf *, - size_t); - -int puffs_framebuf_putdata(struct puffs_framebuf *, const void *, size_t); -int puffs_framebuf_putdata_atoff(struct puffs_framebuf *, size_t, - const void *, size_t); -int puffs_framebuf_getdata(struct puffs_framebuf *, void *, size_t); -int puffs_framebuf_getdata_atoff(struct puffs_framebuf *, size_t, - void *, size_t); - -size_t puffs_framebuf_telloff(struct puffs_framebuf *); -size_t puffs_framebuf_tellsize(struct puffs_framebuf *); -size_t puffs_framebuf_remaining(struct puffs_framebuf *); -int puffs_framebuf_seekset(struct puffs_framebuf *, size_t); -int puffs_framebuf_getwindow(struct puffs_framebuf *, size_t, - void **, size_t *); - -int puffs_framev_enqueue_cc(struct puffs_cc *, int, - struct puffs_framebuf *, int); -int puffs_framev_enqueue_cb(struct puffs_usermount *, int, - struct puffs_framebuf *, - puffs_framev_cb, void *, int); -int puffs_framev_enqueue_justsend(struct puffs_usermount *, int, - struct puffs_framebuf *, int, int); -int puffs_framev_enqueue_directreceive(struct puffs_cc *, int, - struct puffs_framebuf *, int); -int puffs_framev_enqueue_directsend(struct puffs_cc *, int, - struct puffs_framebuf *, int); -int puffs_framev_enqueue_waitevent(struct puffs_cc *, int, int *); -int puffs_framev_framebuf_ccpromote(struct puffs_framebuf *, - struct puffs_cc *); - -int puffs_framev_addfd(struct puffs_usermount *, int, int); -int puffs_framev_enablefd(struct puffs_usermount *, int, int); -int puffs_framev_disablefd(struct puffs_usermount *, int, int); -int puffs_framev_removefd(struct puffs_usermount *, int, int); -void puffs_framev_removeonclose(struct puffs_usermount *, int, int); -void puffs_framev_unmountonclose(struct puffs_usermount *, int, int); - -__END_DECLS - -#endif /* _PUFFS_H_ */ diff --git a/lib/libpuffs/puffs_cc.3 b/lib/libpuffs/puffs_cc.3 deleted file mode 100644 index bee49908e..000000000 --- a/lib/libpuffs/puffs_cc.3 +++ /dev/null @@ -1,94 +0,0 @@ -.\" $NetBSD: puffs_cc.3,v 1.14 2009/04/11 16:48:53 wiz Exp $ -.\" -.\" Copyright (c) 2007, 2008 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd January 28, 2008 -.Dt PUFFS_CC 3 -.Os -.Sh NAME -.Nm puffs_cc -.Nd puffs continuation routines -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft void -.Fn puffs_cc_yield "struct puffs_cc *pcc" -.Ft void -.Fn puffs_cc_continue "struct puffs_cc *pcc" -.Ft void -.Fn puffs_cc_schedule "struct puffs_cc *pcc" -.Ft struct puffs_cc * -.Fn puffs_cc_getcc "struct puffs_usermount *pu" -.Sh DESCRIPTION -These routines are used for the cooperative multitasking suite present -in puffs. -.Pp -.Bl -tag -width xxxx -.It Fn puffs_cc_yield "pcc" -Suspend and save the current execution context and return control -to the previous point. -In practice, from the file system author perspective, control returns -back to where either the mainloop or where -.Fn puffs_dispatch_exec -was called from. -.It Fn puffs_cc_continue pcc -Will suspend current execution and return control to where it was -before before calling -.Fn puffs_cc_yield . -This is rarely called directly but rather through -.Fn puffs_dispatch_exec . -.It Fn puffs_cc_schedule "pcc" -Schedule a continuation. -As opposed to -.Fn puffs_cc_continue -this call returns immediately. -.Fa pcc -will be scheduled sometime in the future. -.It Fn puffs_cc_getcc "pu" -Returns the current pcc or -.Dv NULL -if this is the main thread. -.Em NOTE : -The argument -.Ar pu -will most likely disappear at some point. -.El -.Pp -Before calling -.Fn puffs_cc_yield -a file system will typically want to record some cookie value into its -own internal bookkeeping. -This cookie should be hooked to the -.Va pcc -so that the correct continuation can be continued when the event it -was waiting for triggers. -Alternatively, the -.Xr puffs_framebuf 3 -framework and -.Fn puffs_mainloop -can be used for handling this automatically. -.Sh SEE ALSO -.Xr puffs 3 , -.Xr puffs_framebuf 3 diff --git a/lib/libpuffs/puffs_cred.3 b/lib/libpuffs/puffs_cred.3 deleted file mode 100644 index cd1e69136..000000000 --- a/lib/libpuffs/puffs_cred.3 +++ /dev/null @@ -1,167 +0,0 @@ -.\" $NetBSD: puffs_cred.3,v 1.5 2009/04/11 15:36:22 joerg Exp $ -.\" -.\" Copyright (c) 2007 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd October 18, 2007 -.Dt PUFFS_CRED 3 -.Os -.Sh NAME -.Nm puffs_cred -.Nd puffs credential and access control routines -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft int -.Fn puffs_cred_getuid "const struct puffs_cred *pcr" "uid_t *uid" -.Ft int -.Fn puffs_cred_getgid "const struct puffs_cred *pcr" "gid_t *gid" -.Ft int -.Fo puffs_cred_getgroups -.Fa "const struct puffs_cred *pcr" "gid_t *gids" "short *ngids" -.Fc -.Pp -.Ft bool -.Fn puffs_cred_isuid "const struct puffs_cred *pcr" "uid_t uid" -.Ft bool -.Fn puffs_cred_hasgroup "const struct puffs_cred *pcr" "gid_t gid" -.Ft bool -.Fn puffs_cred_iskernel "const struct puffs_cred *pcr" -.Ft bool -.Fn puffs_cred_isfs "const struct puffs_cred *pcr" -.Ft bool -.Fn puffs_cred_isjuggernaut "const struct puffs_cred *pcr" -.Pp -.Ft int -.Fo puffs_access -.Fa "enum vtype type" "mode_t file_mode" "uid_t owner" "gid_t group" -.Fa "mode_t access_mode" "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_access_chown -.Fa "uid_t owner" "gid_t group" "uid_t newowner" "gid_t newgroup" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_access_chmod -.Fa "uid_t owner" "gid_t group" "enum vtype type" "mode_t newmode" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_access_times -.Fa "uid_t owner" "gid_t group" "mode_t file_mode" "int va_utimes_null" -.Fa "const struct puffs_cred *pcr" -.Fc -.Sh DESCRIPTION -These functions can be used to check operation credentials and perform -access control. -The structure -.Vt struct puffs_cred -can contain two types of credentials: ones belonging to users and -ones belonging to the kernel. -The latter is further divided into generic kernel credentials and -file system credentials. -The general rule is that these should be treated as more powerful -than superuser credentials, but the file system is free to treat -them as it sees fit. -.Ss Credentials -The -.Fn puffs_cred_get -family of functions fetch the uid or gid(s) from the given credential -cookie. -They return 0 for success or \-1 for an error and set -.Va errno . -An error happens when the credentials represent kernel or file system -credentials and do not contain an uid or gid(s). -.Pp -For -.Fn puffs_cred_getgroups , -the argument -.Fa gids -should point to an array with room for -.Fa *ngids -elements. -.Pp -The -.Fn puffs_cred_is -family of functions return 1 if the truth value of the function for -.Fa pcr -is true and 0 if it is false. -The function -.Fn puffs_cred_isjuggernaut -is true if -.Fa pcr -describes superuser, kernel or file system credentials. -.Ss Access Control -To help the programmers task of emulating normal kernel file system -access control semantics, several helper functions are provided to -check if access is allowed. -They return 0 if access should be permitted or an errno value to -indicate that access should be denied with the returned value. -.Pp -.Fn puffs_access -is equivalent to the kernel -.Fn vaccess -function. -The arguments specify current information of the file to be -tested with the exception of -.Fa access_mode , -which is a combination of -.Dv PUFFS_VREAD , -.Dv PUFFS_VWRITE -and -.Dv PUFFS_VEXEC -indicating the desired file access mode. -.Pp -The rest of the functions provide UFS semantics for operations. -.Fn puffs_access_chown -checks if it is permissible to chown a file with the current uid -and gid to the new uid and gid with the credentials of -.Fa pcr . -.Pp -.Fn puffs_access_chmod -checks against permission to chmod a file of type -.Fa type -to the mode -.Fa newmode . -.Pp -Finally, -.Fn puffs_access_times -checks if it is allowable to update the timestamps of a file. -The argument -.Fa va_utimes_null -signals if the flags -.Dv VA_UTIMES_NULL -was set in -.Fa va_vaflags -of -.Va struct vattr . -If coming from a path where this information is unavailable, passing -0 as this argument restricts the permission of modification to the -owner and superuser. -Otherwise the function checks for write permissions to the node and -returns success if the caller has write permissions. -.Sh SEE ALSO -.Xr puffs 3 , -.Xr vnode 9 diff --git a/lib/libpuffs/puffs_flush.3 b/lib/libpuffs/puffs_flush.3 deleted file mode 100644 index a139ac7d9..000000000 --- a/lib/libpuffs/puffs_flush.3 +++ /dev/null @@ -1,113 +0,0 @@ -.\" $NetBSD: puffs_flush.3,v 1.8 2009/02/20 14:26:56 pooka Exp $ -.\" -.\" Copyright (c) 2007 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd April 7, 2007 -.Dt PUFFS_FLUSH 3 -.Os -.Sh NAME -.Nm puffs_flush -.Nd puffs kernel cache flushing and invalidation routines -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft int -.Fo puffs_inval_namecache_dir -.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" -.Fc -.Ft int -.Fn puffs_inval_namecache_all "struct puffs_usermount *pu" -.Ft int -.Fo puffs_inval_pagecache_node -.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" -.Fc -.Ft int -.Fo puffs_inval_pagecache_node_range -.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "off_t start" -.Fa "off_t end" -.Fc -.Ft int -.Fo puffs_flush_pagecache_node -.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" -.Fc -.Ft int -.Fo puffs_flush_pagecache_node_range -.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "off_t start" -.Fa "off_t end" -.Fc -.Sh DESCRIPTION -These routines are used inform the kernel that any information it might -have cached is no longer valid. -.Fn puffs_inval_namecache_dir -invalidates the name cache for a given directory. -The argument -.Va cookie -should describe an existing and valid directory cookie for the file -system. -Similarly, -.Fn puffs_inval_namecache_all -invalidates the name cache for the entire file system -(this routine might go away). -.Pp -The cached pages (file contents) for a regular file described by -.Va cookie -are invalidated using -.Fn puffs_inval_pagecache_node . -A specific range can be invalidated using -.Fn puffs_inval_pagecache_node_range -for a platform specific page level granularity. -The offset -.Va start -will be -.Em truncated -to a page boundary while -.Va end -will be -.Em "rounded up" -to the next page boundary. -As a special case, specifying 0 as -.Va end -will invalidate all contents from -.Va start -to the end of the file. -.Pp -It is especially important to note that these routines will not only -invalidate data in the "read cache", but also data in the "write back" -cache (conceptually speaking; in reality they are the same cache), which -has not yet been flushed to the file server. -Therefore any unflushed data will be lost. -.Pp -The counterparts of the invalidation routines are the flushing routines -.Fn puffs_flush_pagecache_node -and -.Fn puffs_flush_pagecache_node_range , -which force unwritten data from the kernel page cache to be written. -For the flush range version, the same range rules as with the -invalidation routine apply. -The data is flushed asynchronously, i.e. if the routine returns -successfully, all the caller knows is that the data has been queued -for writing. -.Sh SEE ALSO -.Xr puffs 3 diff --git a/lib/libpuffs/puffs_framebuf.3 b/lib/libpuffs/puffs_framebuf.3 deleted file mode 100644 index d698d8316..000000000 --- a/lib/libpuffs/puffs_framebuf.3 +++ /dev/null @@ -1,620 +0,0 @@ -.\" $NetBSD: puffs_framebuf.3,v 1.30 2015/02/16 10:48:50 wiz Exp $ -.\" -.\" Copyright (c) 2007 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd September 6, 2008 -.Dt PUFFS_FRAMEBUF 3 -.Os -.Sh NAME -.Nm puffs_framebuf -.Nd buffering and event handling for networked file systems -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft struct puffs_framebuf * -.Fn puffs_framebuf_make -.Ft void -.Fn puffs_framebuf_destroy "struct puffs_framebuf *pufbuf" -.Ft void -.Fn puffs_framebuf_recycle "struct puffs_framebuf *pufbuf" -.Ft int -.Fn puffs_framebuf_reserve_space "struct puffs_framebuf *pufbuf" "size_t space" -.Ft int -.Fo puffs_framebuf_putdata -.Fa "struct puffs_framebuf *pufbuf" "const void *data" "size_t dlen" -.Fc -.Ft int -.Fo puffs_framebuf_putdata_atoff -.Fa "struct puffs_framebuf *pufbuf" "size_t offset" "const void *data" -.Fa "size_t dlen" -.Fc -.Ft int -.Fo puffs_framebuf_getdata -.Fa "struct puffs_framebuf *pufbuf" "void *data" "size_t dlen" -.Fc -.Ft int -.Fo puffs_framebuf_getdata_atoff -.Fa "struct puffs_framebuf *pufbuf" "size_t offset" -.Fa "void *data" "size_t dlen" -.Fc -.Ft size_t -.Fn puffs_framebuf_telloff "struct puffs_framebuf *pufbuf" -.Ft size_t -.Fn puffs_framebuf_tellsize "struct puffs_framebuf *pufbuf" -.Ft size_t -.Fn puffs_framebuf_remaining "struct puffs_framebuf *pufbuf" -.Ft int -.Fn puffs_framebuf_seekset "struct puffs_framebuf *pufbuf" "size_t offset" -.Ft int -.Fo puffs_framebuf_getwindow -.Fa "struct puffs_framebuf *pufbuf" "size_t offset" -.Fa "void **winp" "size_t *winlen" -.Fc -.Ft int -.Fo puffs_framev_enqueue_cc -.Fa "struct puffs_cc *pcc" "int fd" "struct puffs_framebuf *pufbuf" "int flags" -.Fc -.Ft void -.Fo puffs_framev_cb -.Fa "struct puffs_usermount *pu" "int fd" "struct puffs_framebuf *pufbuf" -.Fa "void *arg" "int flags" -.Fa "int error" -.Fc -.Ft void -.Fo puffs_framev_enqueue_cb -.Fa "struct puffs_usermount *pu" "int fd" "struct puffs_framebuf *pufbuf" -.Fa "puffs_framebuf_cb fcb" "void *fcb_arg" "int flags" -.Fc -.Ft void -.Fo puffs_framev_enqueue_justsend -.Fa "struct puffs_usermount *pu" "int fd" "struct puffs_framebuf *pufbuf" -.Fa "int waitreply" "int flags" -.Fc -.Ft void -.Fo puffs_framev_enqueue_directsend -.Fa "struct puffs_usermount *pu" "int fd" "struct puffs_framebuf *pufbuf" -.Fa "int flags" -.Fc -.Ft void -.Fo puffs_framev_enqueue_directreceive -.Fa "struct puffs_usermount *pu" "int fd" "struct puffs_framebuf *pufbuf" -.Fa "int flags" -.Fc -.Ft int -.Fo puffs_framev_framebuf_ccpromote -.Fa "struct puffs_framebuf *pufbuf" "struct puffs_cc *pcc" -.Fc -.Ft int -.Fn puffs_framev_enqueue_waitevent "struct puffs_cc *pcc" "int fd" "int *what" -.Ft int -.Fo puffs_framev_readframe_fn -.Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pufbuf" -.Fa "int fd" "int *done" -.Fc -.Ft int -.Fo puffs_framev_writeframe_fn -.Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pufbuf" -.Fa "int fd" "int *done" -.Fc -.Ft int -.Fo puffs_framev_cmpframe_fn -.Fa "struct puffs_usermount *pu" -.Fa "struct puffs_framebuf *cmp1" "struct puffs_framebuf *cmp2" "int *notresp" -.Fc -.Ft void -.Fo puffs_framev_gotframe_fn -.Fa "struct puffs_usermount *pu" "struct puffs_framebuf *pufbuf" -.Fc -.Ft void -.Fo puffs_framev_fdnotify_fn -.Fa "struct puffs_usermount *pu" "int fd" "int what" -.Fc -.Ft void -.Fo puffs_framev_init -.Fa "struct puffs_usermount *pu" -.Fa "puffs_framev_readframe_fn rfb" "puffs_framev_writeframe_fn wfb" -.Fa "puffs_framev_cmpframe_fn cmpfb" "puffs_framev_gotframe_fn gotfb" -.Fa "puffs_framev_fdnotify_fn fdnotfn" -.Fc -.Ft int -.Fn puffs_framev_addfd "struct puffs_usermount *pu" "int fd" "int what" -.Ft int -.Fn puffs_framev_enablefd "struct puffs_usermount *pu" "int fd" "int what" -.Ft int -.Fn puffs_framev_disablefd "struct puffs_usermount *pu" "int fd" "int what" -.Ft int -.Fn puffs_framev_removefd "struct puffs_usermount *pu" "int fd" "int error" -.Ft void -.Fo puffs_framev_unmountonclose -.Fa "struct puffs_usermount *pu" "int fd" "int what" -.Fc -.Sh DESCRIPTION -The -.Nm -routines provide buffering and an event loop structured around the -buffers. -It operates on top of the puffs continuation framework, -.Xr puffs_cc 3 , -and multiplexes execution automatically to an instance whenever -one is runnable. -.Pp -The file system is entered in three different ways: -.Bl -bullet -offset indent -.It -An event arrives from the kernel and the -.Xr puffs_ops 3 -callbacks are called to start processing the event. -.It -A file system which has sent out a request receives a response. -Execution is resumed from the place where the file system yielded. -.It -A request from a peer arrives. -A request is an incoming PDU which is not a response to any outstanding -request. -.El -.Pp -.Nm -is used by defining various callbacks and providing I/O descriptors, -which are then monitored for activity by the library. -A descriptor, when present, can be either enabled or disabled for -input and output. -If a descriptor is not enabled for a certain direction, the callbacks -will not be called even if there were activity on the descriptor. -For example, even if a network socket has been added and there is -input data in the socket buffer, the read callback will be called -only if the socket has been enabled for reading. -.Pp -File descriptors are treated like sockets: they have two sides, a read -side and a write side. -The framework determines that one side of the descriptor has been -closed if the supplied I/O callbacks return an error or if the I/O -multiplexing call says a side has been closed. -It is still possible, from the framework perspective, to write to a -file descriptor whose read side is closed. -However, it is not possible to wait for a response on such a file -descriptor. -Conversely, it is possible to read responses from a descriptor whose -write side is closed. -It should be stressed that the implementation underlying the file -descriptor might not support this. -.Pp -The following callbacks can be defined, cf. -.Fn puffs_framev_init , -and all are optional. -None of them should block, because this would cause the entire file server -to block. -One option is to make the descriptors non-blocking before adding them. -.Bl -tag -width "xfdnotfnx" -.It rfb -Read a frame from the file descriptor onto the specified buffer. -.It wfb -Write a frame from the specified buffer into the file descriptor. -.It cmpfb -Identify if a buffer is the response to the specified buffer. -.It gotfb -Called iff no outstanding request matches the incoming frame. -In other words, this is called when we receive a request from a peer. -.It fdnotfn -Receive notifications about a change-of-state in a file descriptor's -status. -.El -.Pp -Better descriptions for each callback are given below. -.Pp -The buffers of -.Nm -provide automatic memory management of buffers for the file servers. -They provide a cursor to the current buffer offset. -Reading or writing data through the normal routines will advance that cursor. -Additionally, the buffer size is provided to the user. -It represents the maximum offset where data was written. -.Pp -Generally the write functions will fail if the cannot allocate enough -memory to satisfy the buffer length requirements. -Read functions will fail if the amount of data written to the buffer -is not large enough to satisfy the read. -.Bl -tag -width xxxx -.It Fn puffs_framebuf_make -Create a buffer. -Return the address of the buffer or -.Dv NULL -in case no memory was available. -.It Fn puffs_framebuf_destroy pufbuf -Free memory used by buffer. -.It Fn puffs_framebuf_recycle pufbuf -Reset offsets so that buffer can be reused. -Does not free memory or reallocate memory. -.It Fn puffs_framebuf_reserve_space pufbuf space -Make sure that the buffer has -.Ar space -bytes of available memory starting from the current offset. -This is not strictly necessary, but can be used for optimizations -where it is known in advance how much memory will be required. -.It Fn puffs_framebuf_putdata pufbuf data dlen -Write -.Ar dlen -amount of data from the address -.Ar data -into the buffer. -Moves the offset cursor forward -.Ar dlen -bytes. -.It Fn puffs_framebuf_putdata_atoff pufbuf offset data dlen -Like -.Fn puffs_framebuf_putdata , -except writes data at buffer offset -.Ar offset . -It is legal to write past the current end of the buffer. -Does NOT modify the current offset cursor. -.It Fn puffs_framebuf_getdata pufbuf data dlen -Read -.Ar dlen -bytes of data from the buffer into -.Ar data . -Advances the offset cursor. -.It Fn puffs_framebuf_getdata_atoff pufbuf offset data dlen -Read data from buffer position -.Ar offset . -Does NOT modify the offset cursor. -.It Fn puffs_framebuf_telloff pufbuf -Return the offset into the buffer. -.It Fn puffs_framebuf_tellsize pufbuf -Return the maximum offset where data has been written, i.e. buffer size. -.It Fn puffs_framebuf_remaining pufbuf -Distance from current offset to the end of the buffer, i.e. size-offset. -.It Fn puffs_framebuf_seekset pufbuf offset -Set the offset cursor to the position -.Ar offset . -This does NOT modify the buffer size, but reserves at least -enough memory memory for a write to -.Ar offset -and will fail if memory cannot be allocated. -.It Fn puffs_framebuf_getwindow pufbuf offset winp winlen -Get a direct memory window into the buffer starting from -.Ar offset . -The maximum mapped window size will be -.Ar winlen -bytes, but this routine might return a smaller window and the caller -should always check the actual mapped size after the call. -The window is returned in -.Ar winp . -This function not modify the buffer offset, but it DOES set the buffer -size to -.Ar offset + -.Ar winlen -in case that value is greater than the current size. -The window is valid until the next until the next -.Fn puffs_framebuf -call operating on the buffer in question. -.It Fn puffs_framev_enqueue_cc pcc fd pufbuf flags -Add the buffer -.Ar pufbuf -to outgoing queue of descriptor -.Ar fd -and yield with the continuation -.Ar pcc . -Execution is resumed once a response is received. -Returns 0 if the buffer was successfully enqueued (not necessarily -delivered) and non-zero to signal a non-recoverable error. -.Pp -Usually the buffer is placed at the end of the output queue. -However, if -.Ar flags -contains -.Dv PUFFS_FBQUEUE_URGENT , -.Ar pufbuf -is placed in the front of the queue to be sent immediately after -the current PDU (if any) has been sent. -.It Fn puffs_framev_enqueue_cb pu fd pufbuf fcb fcb_arg flags -Enqueue the buffer -.Ar pufbuf -for outgoing data and immediately return. -Once a response arrives, the callback -.Fn fcb -will be called with the argument -.Ar fcb_arg . -The callback function -.Fn fcb -is responsible for freeing the buffer. -Returns 0 if the buffer was successfully enqueued (not necessarily -delivered) and non-zero to signal a non-recoverable error. -.Pp -See -.Fn puffs_framev_enqueue_cc -for -.Ar flags . -.It Fn puffs_framev_cb pu pufbuf arg error -Callback function. -Called when a response to a specific request arrives from the server. -If -.Ar error -is non-zero, the framework was unable to obtain a response and the -function should not examine the contents of -.Ar pufbuf , -only do resource cleanup. -May not block. -.It Fn puffs_framev_enqueue_justsend pu fd pufbuf waitreply flags -Enqueue the buffer -.Ar pufbuf -for outgoing traffic and immediately return. -The parameter -.Ar waitreply -can be used to control if the buffer is to be freed immediately after -sending of if a response is expected and the buffer should be freed -only after the response arrives (receiving an unexpected message from -the server is treated as an error). -Returns 0 if the buffer was successfully enqueued (not necessarily -delivered) and non-zero to signal a non-recoverable error. -.Pp -See -.Fn puffs_framev_enqueue_cc -for -.Ar flags . -.It Fn puffs_framev_enqueue_directsend pcc fd pufbuf flags -Acts like -.Fn puffs_framev_enqueue_justsend -with the exception that the call yields until the frame has been sent. -As opposed to -.Fn puffs_framev_enqueue_cc , -the routine does not wait for input, but returns immediately after -sending the frame. -.Pp -See -.Fn puffs_framev_enqueue_cc -for -.Ar flags . -.It Fn puffs_framev_enqueue_directreceive pcc fd pufbuf flags -Receive data into -.Ar pufbuf . -This routine yields until a complete frame has been read into -the buffer by the readframe routine. -.Pp -See -.Fn puffs_framev_enqueue_cc -for -.Ar flags . -.It Fn puffs_framev_framebuf_ccpromote pufbuf pcc -Promote the framebuffer -.Ar pufbuf -sent with -.Fn puffs_framev_enqueue_cb -or -.Fn puffs_framev_enqueue_justsend -to a wait using -.Ar pcc -and yield until the result arrives. -The response from the file server for -.Ar pufbuf -must not yet have arrived. -If sent with -.Fn puffs_framev_enqueue_justsend , -the call must be expecting a response. -.It Fn puffs_framev_enqueue_waitevent pcc fd what -Waits for an event in -.Ar what -to happen on file descriptor -.Ar fd . -The events which happened are returned back in -.Ar what . -The possible events are -.Dv PUFFS_FBIO_READ , -.Dv PUFFS_FBIO_WRITE , -and -.Dv PUFFS_FBIO_ERROR , -specifying read, write and error conditions, respectively. -Error is always checked. -.Pp -This call does not depend on if the events were previously enabled on -the file descriptor - the specified events are always checked -regardless. -.Pp -There is currently no other way to cancel or timeout a call except by -removing the file descriptor in question. -This may change in the future. -.It Fn puffs_framev_readframe_fn pu pufbuf fd done -Callback function. -Read at most one frame from file descriptor -.Ar fd -into the buffer -.Ar pufbuf . -If a complete frame is read, the value pointed to by -.Ar done -must be set to 1. -This function should return 0 on success (even if a complete frame was not -yet read) and a non-zero -.Er errno -to signal a fatal error. -In case a fatal error is returned, the read side of the file descriptor -is marked closed. -This routine will be called with the same buffer argument until a -complete frame has been read. -May not block. -.It Fn puffs_framev_writeframe_fn pu pufbuf fd done -Write the frame contained in -.Ar pufbuf -to the file descriptor -.Ar fd . -In case the entire frame is successfully written, -.Ar *done -should be set to 1. -This function should return 0 on success (even if a complete frame was not -yet written) and a non-zero -.Er errno -to signal a fatal error. -In case a fatal error is returned, the write side of the file descriptor -is marked closed. -This routine will be called with the same buffer argument until the -complete frame has been written. -May not block. -.Pp -It is a good idea to make sure that this function can handle a possible -.Dv SIGPIPE -caused by a closed connection. -For example, the file server can opt to trap -.Dv SIGPIPE -or, if writing to a socket, call -.Fn send -with the flag -.Dv MSG_NOSIGNAL -instead of using -.Fn write . -.It Fn puffs_framev_cmpframe_fn pu pufbuf_cmp1 pufbuf_cmp2 notresp -Compare the file system internal request tags in -.Ar pufbuf_cmp1 -and -.Ar pufbuf_cmp2 . -Should return 0 if the tags are equal, 1 if first buffer's tag is -greater than the second and \-1 if it is smaller. -The definitions "greater" and "smaller" are used transparently by -the library, e.g. like -.Xr qsort 3 . -If it can be determined from -.Ar pufbuf_cmp1 -that it is not a response to any outstanding request, -.Ar notresp -should be set to non-zero. -This will cause -.Nm -to skip the test of the buffer against the rest of the outstanding -request. -May not block. -.It Fn puffs_framev_gotframe_fn pu pufbuf -Called when no outstanding request matches an incoming frame. -The ownership of -.Ar pufbuf -is transferred to the called function and must be destroyed once -processing is over. -May not block. -.It Fn puffs_framev_fdnotify_fn pu fd what -Is called when the read or write side of the file descriptor -.Ar fd -is closed. -It is called once for each side, the bitmask parameter -.Ar what -specified what is currently closed: -.Dv PUFFS_FBIO_READ -and -.Dv PUFFS_FBIO_WRITE -for read and write, respectively. -.It Fn puffs_framev_init pu rfb wfb cmpfb gotfb fdnotfn -Initializes the given callbacks to the system. -They will be used when -.Fn puffs_mainloop -is called. -The framework provides the routines -.Fn puffs_framev_removeonclose -and -.Fn puffs_framev_unmountonclose , -which can be given as -.Ar fdnotfn . -The first one removes the file descriptor once both sides are closed -while the second one unmounts the file system and exits the mainloop. -.It Fn puffs_framev_addfd pu fd what -Add file descriptor -.Ar fd -to be handled by the framework. -It is legal to add a file descriptor either before calling -.Fn puffs_mainloop -or at time when running. -The parameter -.Ar what -controls enabling of input and output events and can be a bitwise -combination of -.Dv PUFFS_FBIO_READ -and -.Dv PUFFS_FBIO_WRITE . -If not specified, the descriptor will be in a disabled state. -.It Fn puffs_framev_enablefd pu fd what -Enable events of type -.Ar what -for file descriptor -.Ar fd . -.It Fn puffs_framev_disablefd pu fd what -Disable events of type -.Ar what -for file descriptor -.Ar fd . -.It Fn puffs_framev_removefd pu fd error -Remove file descriptor -.Ar fd -from the list of descriptors handled by the framework. -Removing a file descriptor causes all operations blocked either on -output or input to be released with the error value -.Ar error . -In case 0 is supplied as this parameter, -.Er ECONNRESET -is used. -.Pp -The file system -.Em must -explicitly remove each fd it has added. -A good place to do this is -.Fn puffs_framev_fdnotify_fn -or -.Fn puffs_node_reclaim , -depending a little on the structure of the file system. -.It Fn puffs_framev_unmountonclose pu fd what -This is library provided convenience routine for -.Fn puffs_framev_fdnotify_fn . -It unmounts the file system when both the read and write side are -closed. -It is useful for file systems such as -.Xr mount_psshfs 8 -which depend on a single connection. -.El -.Sh RETURN VALUES -These functions generally return \-1 to signal error and set -.Er errno -to indicate the type of error. -.Sh CODE REFERENCES -The current users of -.Nm -in the tree are -.Xr mount_psshfs 8 -and -.Xr mount_9p 8 . -See -.Pa src/usr.sbin/puffs/mount_psshfs -and -.Pa src/usr.sbin/puffs/mount_9p -for the respective usage examples. -.Sh SEE ALSO -.Xr puffs 3 , -.Xr puffs_cc 3 , -.Xr puffs_ops 3 -.Rs -.%A Antti Kantee -.%D September 2007 -.%I Helsinki University of Technology -.%R Tech Report TKK-TKO-B157 -.%T Using puffs for Implementing Client-Server Distributed File Systems -.Re -.Rs -.%A Antti Kantee -.%D March 2008 -.%J Proceedings of AsiaBSDCon 2008 -.%P pp. 55-70 -.%T Send and Receive of File System Protocols: Userspace Approach With puffs -.Re diff --git a/lib/libpuffs/puffs_node.3 b/lib/libpuffs/puffs_node.3 deleted file mode 100644 index 2eb6da0ef..000000000 --- a/lib/libpuffs/puffs_node.3 +++ /dev/null @@ -1,101 +0,0 @@ -.\" $NetBSD: puffs_node.3,v 1.5 2009/05/13 22:42:31 wiz Exp $ -.\" -.\" Copyright (c) 2007 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd June 24, 2007 -.Dt PUFFS_NODE 3 -.Os -.Sh NAME -.Nm puffs_node -.Nd puffs node routines -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft struct puffs_node * -.Fn puffs_pn_new "struct puffs_usermount *pu" "void *priv" -.Ft void * -.Fo puffs_nodewalk_fn -.Fa "struct puffs_usermount *pu" "struct puffs_node *pn" "void *arg" -.Fc -.Ft void * -.Fo puffs_pn_nodewalk -.Fa "struct puffs_usermount *pu" "puffs_nodewalk_fn nwfn" "void *arg" -.Fc -.Ft void -.Fn puffs_pn_remove "struct puffs_node *pn" -.Ft void -.Fn puffs_pn_put "struct puffs_node *pn" -.Sh DESCRIPTION -.Bl -tag -width xxxx -.It Fn puffs_pn_new pu priv -Create a new node and attach it to the mountpoint -.Ar pu . -The argument -.Ar priv -can be used for associating file system specific data with the new -node and will not be accessed by puffs. -.It Fn puffs_nodewalk_fn pu pn arg -A callback for -.Fn puffs_nodewalk . -The list of nodes is iterated in the argument -.Ar pn -and the argument -.Ar arg -is the argument given to -.Fn puffs_nodewalk . -.It Fn puffs_nodewalk pu nwfn arg -Walk all nodes associted with the mountpoint -.Ar pu -and call -.Fn nwfn -for them. -The walk is aborted if -.Fn puffs_nodewalk_fn -returns a value which is not -.Dv NULL . -This value is also returned this function. -In case the whole set of nodes is traversed, -.Dv NULL -is returned. -This function is useful for example in handling the -.Fn puffs_fs_sync -callback, when cached data for every node should be flushed to stable -storage. -.It Fn puffs_pn_remove pn -Signal that a node has been removed from the file system, but do not -yet release resources associated with the node. -This will prevent the nodewalk functions from accessing the node. -If necessary, this is usually called from -.Fn puffs_node_remove -and -.Fn puffs_node_rmdir . -.It Fn puffs_pn_put pn -Free all resources associated with node -.Ar pn . -This is typically called from -.Fn puffs_node_reclaim . -.El -.Sh SEE ALSO -.Xr puffs 3 diff --git a/lib/libpuffs/puffs_ops.3 b/lib/libpuffs/puffs_ops.3 deleted file mode 100644 index f56651920..000000000 --- a/lib/libpuffs/puffs_ops.3 +++ /dev/null @@ -1,955 +0,0 @@ -.\" $NetBSD: puffs_ops.3,v 1.42 2015/02/16 10:48:56 wiz Exp $ -.\" -.\" Copyright (c) 2007 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd October 31, 2014 -.Dt PUFFS_OPS 3 -.Os -.Sh NAME -.Nm puffs_ops -.Nd puffs callback operations -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft int -.Fo puffs_fs_statvfs -.Fa "struct puffs_usermount *pu" "struct statvfs *sbp" -.Fc -.Ft int -.Fo puffs_fs_sync -.Fa "struct puffs_usermount *pu" "int waitfor" "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_fs_fhtonode -.Fa "struct puffs_usermount *pu" "void *fid" "size_t fidsize" -.Fa "struct puffs_newinfo *pni" -.Fc -.Ft int -.Fo puffs_fs_nodetofh -.Fa "struct puffs_usermount *pu" "puffs_cookie_t cookie" "void *fid" -.Fa "size_t *fidsize" -.Fc -.Ft void -.Fo puffs_fs_extattrctl -.Fa "struct puffs_usermount *pu" "int cmd" "puffs_cookie_t cookie" "int flags" -.Fa "int attrnamespace" "const char *attrname" -.Fc -.Ft int -.Fo puffs_fs_unmount -.Fa "struct puffs_usermount *pu" "int flags" -.Fc -.Ft int -.Fo puffs_node_lookup -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn" -.Fc -.Ft int -.Fo puffs_node_create -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn" -.Fa "const struct vattr *vap" -.Fc -.Ft int -.Fo puffs_node_mknod -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn" -.Fa "const struct vattr *vap" -.Fc -.Ft int -.Fo puffs_node_open -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_open2 -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int modep" -.Fa "const struct puffs_cred *pcr" "int *oflags" -.Fc -.Ft int -.Fo puffs_node_close -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_access -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int mode" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_getattr -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_setattr -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "const struct vattr *vap" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_getattr_ttl -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct vattr *vap" -.Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl" -.Fc -.Ft int -.Fo puffs_node_setattr_ttl -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "const struct vattr *vap" -.Fa "const struct puffs_cred *pcr" "struct timespec *va_ttl" "int xflag" -.Fc -.Ft int -.Fo puffs_node_poll -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int *events" -.Fc -.Ft int -.Fo puffs_node_mmap -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int flags" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_fsync -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "const struct puffs_cred *pcr" "int flags" "off_t offlo" "off_t offhi" -.Fc -.Ft int -.Fo puffs_node_seek -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t oldoff" -.Fa "off_t newoff" "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_remove -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ" -.Fa "const struct puffs_cn *pcn" -.Fc -.Ft int -.Fo puffs_node_link -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ" -.Fa "const struct puffs_cn *pcn" -.Fc -.Ft int -.Fo puffs_node_rename -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t src" -.Fa "const struct puffs_cn *pcn_src" "puffs_cookie_t targ_dir" -.Fa "puffs_cookie_t targ" "const struct puffs_cn *pcn_targ" -.Fc -.Ft int -.Fo puffs_node_mkdir -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "struct puffs_newinfo *pni" "const struct puffs_cn *pcn" -.Fa "const struct vattr *vap" -.Fc -.Ft int -.Fo puffs_node_rmdir -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "puffs_cookie_t targ" -.Fa "const struct puffs_cn *pcn" -.Fc -.Ft int -.Fo puffs_node_readdir -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "struct dirent *dent" -.Fa "off_t *readoff" "size_t *reslen" "const struct puffs_cred *pcr" -.Fa "int *eofflag" "off_t *cookies" "size_t *ncookies" -.Fc -.Ft int -.Fo puffs_node_symlink -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "struct puffs_newinfo *pni" -.Fa "const struct puffs_cn *pcn_src" "const struct vattr *vap" -.Fa "const char *link_target" -.Fc -.Ft int -.Fo puffs_node_readlink -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "const struct puffs_cred *pcr" "char *link" "size_t *linklen" -.Fc -.Ft int -.Fo puffs_node_read -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf" -.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag" -.Fc -.Ft int -.Fo puffs_node_write -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf" -.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag" -.Fc -.Ft int -.Fo puffs_node_write2 -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "uint8_t *buf" -.Fa "off_t offset" "size_t *resid" "const struct puffs_cred *pcr" "int ioflag" -.Fa "int xflag" -.Fc -.Ft int -.Fo puffs_node_abortop -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fa "const struct puffs_cn *pcn" -.Fc -.Ft int -.Fo puffs_node_getextattr -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace" -.Fa "const char *attrname" "size_t *attrsize" "uint8_t *attr" "size_t *resid" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_setextattr -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace" -.Fa "const char *attrname" "uint8_t *attr" "size_t *resid" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_listextattr -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace" -.Fa "size_t *attrssize" "uint8_t *attrs" "iint flag" "size_t *resid" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_deleteextattr -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace" -.Fa "const char *attrname" -.Fa "const struct puffs_cred *pcr" -.Fc -.Ft int -.Fo puffs_node_fallocate -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t pos" "off_t len" -.Fc -.Ft int -.Fo puffs_node_fdiscard -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "off_t pos" "off_t len" -.Fc -.Ft int -.Fo puffs_node_print -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fc -.Ft int -.Fo puffs_node_reclaim -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fc -.Ft int -.Fo puffs_node_reclaim2 -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int nlookup" -.Fc -.Ft int -.Fo puffs_node_inactive -.Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" -.Fc -.Ft void -.Fn puffs_setback "struct puffs_cc *pcc" "int op" -.Ft void -.Fn puffs_newinfo_setcookie "struct puffs_newinfo *pni" "puffs_cookie_t cookie" -.Ft void -.Fn puffs_newinfo_setvtype "struct puffs_newinfo *pni" "enum vtype vtype" -.Ft void -.Fn puffs_newinfo_setsize "struct puffs_newinfo *pni" "voff_t size" -.Ft void -.Fn puffs_newinfo_setrdev "struct puffs_newinfo *pni" "dev_t rdev" -.Ft void -.Fn puffs_newinfo_setva "struct puffs_newinfo *pni" "struct vattr *vap" -.Ft void -.Fn puffs_newinfo_setvattl "struct puffs_newinfo *pni" "struct timespec *va_ttl" -.Ft void -.Fn puffs_newinfo_setcnttl "struct puffs_newinfo *pni" "struct timespec *cn_ttl" -.Sh DESCRIPTION -The operations -.Nm puffs -requires to function can be divided into two categories: file system -callbacks and node callbacks. -The former affect the entire file system while the latter are targeted -at a file or a directory and a file. -They are roughly equivalent to the vfs and vnode operations in the -kernel. -.Pp -All callbacks can be prototyped with the file system name and operation -name using the macro -.Fn PUFFSOP_PROTOS fsname . -.Ss File system callbacks (puffs_fs) -.Bl -tag -width xxxx -.It Fn puffs_fs_statvfs "pu" "sbp" -The following fields of the argument -.Fa sbp -need to be filled: -.Bd -literal - * unsigned long f_bsize; file system block size - * unsigned long f_frsize; fundamental file system block size - * fsblkcnt_t f_blocks; number of blocks in file system, - * (in units of f_frsize) - * - * fsblkcnt_t f_bfree; free blocks avail in file system - * fsblkcnt_t f_bavail; free blocks avail to non-root - * fsblkcnt_t f_bresvd; blocks reserved for root - - * fsfilcnt_t f_files; total file nodes in file system - * fsfilcnt_t f_ffree; free file nodes in file system - * fsfilcnt_t f_favail; free file nodes avail to non-root - * fsfilcnt_t f_fresvd; file nodes reserved for root - -.Ed -.It Fn puffs_fs_sync "pu" "waitfor" "pcr" -All the dirty buffers that have been cached at the file server -level including metadata should be committed to stable storage. -The -.Fa waitfor -parameter affects the operation. -Possible values are: -.Bl -tag -width XMNT_NOWAITX -.It Dv MNT_WAIT -Wait for all I/O for complete until returning. -.It Dv MNT_NOWAIT -Initiate I/O, but do not wait for completion. -.It Dv MNT_LAZY -Synchorize data not synchoronized by the file system syncer, -i.e., data not written when -.Fn node_fsync -is called with -.Dv FSYNC_LAZY . -.El -.Pp -The credentials for the initiator of the sync operation are present in -.Fa pcr -and will usually be either file system or kernel credentials, but might -also be user credentials. -However, most of the time it is advisable to sync regardless of the -credentials of the caller. -.It Fn puffs_fs_fhtonode "pu" "fid" "fidsize" "pni" -Translates a file handle -.Fa fid -to a node. -The parameter -.Fa fidsize -indicates how large the file handle is. -In case the file system's handles are static length, this parameter can -be ignored as the kernel guarantees all file handles passed to the file -server are of correct length. -For dynamic length handles the field should be examined and -.Er EINVAL -returned in case the file handle length is not correct. -.Pp -This function provides essentially the same information to the kernel as -.Fn puffs_node_lookup . -The information is necessary for creating a new vnode corresponding to -the file handle. -.It Fn puffs_fs_nodetofh "pu" "cookie" "fid" "fidsize" -Create a file handle from the node described by -.Fa cookie . -The file handle should contain enough information to reliably identify -the node even after reboots and the pathname/inode being replaced by -another file. -If this is not possible, it is up to the author of the file system to -act responsibly and decide if the file system can support file handles -at all. -.Pp -For file systems which want dynamic length file handles, this function -must check if the file handle space indicated by -.Fa fidsize -is large enough to accommodate the file handle for the node. -If not, it must fill in the correct size and return -.Er E2BIG . -In either case, the handle length should be supplied to the kernel in -.Fa fidsize . -File systems with static length handles can ignore the size parameter as -the kernel always supplies the correct size buffer. -.It Fn puffs_fs_unmount "pu" "flags" -Unmount the file system. -The kernel has assumedly flushed all cached data when this callback -is executed. -If the file system cannot currently be safely be unmounted, for whatever -reason, the kernel will honor an error value and not forcibly unmount. -However, if the flag -.Dv MNT_FORCE -is not honored by the file server, the kernel will forcibly unmount -the file system. -.El -.Ss Node callbacks -These operations operate in the level of individual files. -The file cookie is always provided as the second argument -.Fa opc . -If the operation is for a file, it will be the cookie of the file. -The case the operation involves a directory (such as -.Dq create file in directory ) , -the cookie will be for the directory. -Some operations take additional cookies to describe the rest of -the operands. -The return value 0 signals success, else an appropriate errno value -should be returned. -Please note that neither this list nor the descriptions are complete. -.Bl -tag -width xxxx -.It Fn puffs_node_lookup "pu" "opc" "pni" "pcn" -This function is used to locate nodes, or in other words translate -pathname components to file system data structures. -The implementation should match the name in -.Fa pcn -against the existing entries in the directory provided by the cookie -.Fa opc . -If found, the cookie for the located node should be set in -.Fa pni -using -.Fn puffs_newinfo_setcookie . -Additionally, the vnode type and size (latter applicable to regular files only) -should be set using -.Fn puffs_newinfo_setvtype -and -.Fn puffs_newinfo_setsize , -respectively. -If the located entry is a block device or character device file, -the dev_t for the entry should be set using -.Fn puffs_newinfo_setrdev . -.Pp -If -.Fn puffs_init -was called with -.Dv PUFFS_KFLAG_CACHE_FS_TTL -then -.Fn puffs_newinfo_setva , -.Fn puffs_newinfo_setvattl , -and -.Fn puffs_newinfo_setcnttl -can be called to specify the new node attributes, cached attributes -time to live, and cached name time to live. -.Pp -The type of operation is found from -.Va pcn-\*[Gt]pcn_nameiop : -.Bl -tag -width XNAMEI_LOOKUPX -.It Dv NAMEI_LOOKUP -Normal lookup operation. -.It Dv NAMEI_CREATE -Lookup to create a node. -.It Dv NAMEI_DELETE -Lookup for node deletion. -.It Dv NAMEI_RENAME -Lookup for the target of a rename operation (source will be looked -up using -.Dv NAMEI_DELETE ) . -.El -.Pp -The final component from a pathname lookup usually requires special -treatment. -It can be identified by looking at the -.Va pcn-\*[Gt]pcn_flags -fields for the flag -.Dv PUFFSLOOKUP_ISLASTCN . -For example, in most cases the lookup operation will want to check if -a delete, rename or create operation has enough credentials to perform -the operation. -.Pp -The return value 0 signals a found node and a nonzero value signals -an errno. -As a special case, -.Er ENOENT -signals "success" for cases where the lookup operation is -.Dv NAMEI_CREATE -or -.Dv NAMEI_RENAME . -Failure in these cases can be signalled by returning another appropriate -error code, for example -.Er EACCESS . -.Pp -Usually a null-terminated string for the next pathname component is -provided in -.Ar pcn-\*[Gt]pcn_name . -In case the file system is using the option -.Dv PUFFS_KFLAG_LOOKUP_FULLPNBUF , -the remainder of the complete pathname under lookup is found in -the same location. -.Ar pcn-\*[Gt]pcn_namelen -always specifies the length of the next component. -If operating with a full path, the file system is allowed to consume -more than the next component's length in node lookup. -This is done by setting -.Ar pcn-\*[Gt]pcn_consume -to indicate the amount of -.Em extra -characters in addition to -.Ar pcn-\*[Gt]pcn_namelen -processed. -.It Fn puffs_node_create "pu" "opc" "pni" "pcn" "va" -.It Fn puffs_node_mkdir "pu" "opc" "pni" "pcn" "va" -.It Fn puffs_node_mknod "pu" "opc" "pni" "pcn" "va" -A file node is created in the directory denoted by the cookie -.Fa opc -by any of the above callbacks. -The name of the new file can be found from -.Fa pcn -and the attributes are specified by -.Fa va -and the cookie for the newly created node should be set in -.Fa pni . -The only difference between these three is that they create a regular -file, directory and device special file, respectively. -.Pp -In case of mknod, the device identifier can be found in -.Fa va-\*[Gt]va_rdev . -.It Fn puffs_node_open "pu" "opc" "mode" "pcr" -.It Fn puffs_node_open2 "pu" "opc" "mode" "pcr" "oflags" -Open the node denoted by the cookie -.Fa opc . -The parameter -.Fa mode -specifies the flags that -.Xr open 2 -was called with, e.g. -.Dv O_APPEND -and -.Dv O_NONBLOCK . -.Fn puffs_node_open2 -allows the file system to pass back information for the file in -.Fa oflags . -The only implemented flag for now is -.Dv PUFFS_OPEN_IO_DIRECT -that cause file read/write to bypass the page cache. -.It Fn puffs_node_close "pu" "opc" "flags" "pcr" -Close a node. -The parameter -.Fa flags -parameter describes the flags that the file was opened with. -.It Fn puffs_node_access "pu" "opc" "mode" "pcr" -Check if the credentials of -.Fa pcr -have the right to perform the operation specified by -.Fa mode -onto the node -.Fa opc . -The argument -.Fa mode -can specify read, write or execute by -.Dv PUFFS_VREAD , -.Dv PUFFS_VWRITE , -and -.Dv PUFFS_VEXEC , -respectively. -.It Fn puffs_node_getattr "pu" "opc" "va" "pcr" -The attributes of the node specified by -.Fa opc -must be copied to the space pointed by -.Fa va . -.It Fn puffs_node_getattr_ttl "pu" "opc" "va" "pcr" "va_ttl" -Same as -.Fn puffs_node_getattr -with cached attribute time to live specified in -.Fa va_ttl -.It Fn puffs_node_setattr "pu" "opc" "va" "pcr" -The attributes for the node specified by -.Fa opc -must be set to those contained in -.Fa va . -Only fields of -.Fa va -which contain a value different from -.Dv PUFFS_VNOVAL -(typecast to the field's type!) contain a valid value. -.It Fn puffs_node_setattr_ttl "pu" "opc" "va" "pcr" "va_ttl" "xflag" -Same as -.Fn puffs_node_setattr -with cached attribute time to live specified in -.Fa va_ttl . -.Dv PUFFS_SETATTR_FAF -will be set in -.Fa xflag -for Fire-And-Forget operations. -.It Fn puffs_node_poll "pu" "opc" "events" -Poll for events on node -.Ar opc . -If -.Xr poll 2 -events specified in -.Ar events -are available, the function should set the bitmask to match available -events and return immediately. -Otherwise, the function should block (yield) until some events in -.Ar events -become available and only then set the -.Ar events -bitmask and return. -.Pp -In case this function returns an error, -.Dv POLLERR -(or its -.Xr select 2 -equivalent) will be delivered to the calling process. -.Pp -.Em NOTE! -The system call interface for -.Fn poll -contains a timeout parameter. -At this level, however, the timeout is not supplied. -In case input does not arrive, the file system should periodically -unblock and return 0 new events to avoid hanging forever. -This will hopefully be better supported by libpuffs in the future. -.It Fn puffs_node_mmap "pu" "opc" "flags" "pcr" -Called when a regular file is being memory mapped by -.Xr mmap 2 . -.Fa flags -is currently always 0. -.It Fn puffs_node_fsync "pu" "opc" "pcr" "flags" "offlo" "offhi" -Sychronize a node's contents onto stable storage. -This is necessary only if the file server caches some information -before committing it. -The parameter -.Fa flags -specifies the minimum level of sychronization required (XXX: they are -not yet available). -The parameters -.Fa offlo -and -.Fa offhi -specify the data offsets requiring to be synced. -A high offset of 0 means sync from -.Fa offlo -to the end of the file. -.It Fn puffs_node_seek "pu" "opc" "oldoff" "newoff" "pcr" -Test if the node -.Ar opc -is seekable to the location -.Ar newoff . -The argument -.Ar oldoff -specifies the offset we are starting the seek from. -Most file systems dealing only with regular will choose to not -implement this. -However, it is useful for example in cases where files are -unseekable streams. -.It Fn puffs_node_remove "pu" "opc" "targ" "pcn" -.It Fn puffs_node_rmdir "pu" "opc" "targ" "pcn" -Remove the node -.Fa targ -from the directory indicated by -.Fa opc . -The directory entry name to be removed is provided by -.Fa pcn . -The rmdir operation removes only directories, while the remove -operation removes all other types except directories. -.Pp -It is paramount to note that the file system may not remove the -node data structures at this point, only the directory entry and prevent -lookups from finding the node again. -This is to retain the -.Ux -open file semantics. -The data may be removed only when -.Fn puffs_node_reclaim -or -.Fn puffs_node_reclaim2 -is called for the node, as this assures there are no further users. -.It Fn puffs_node_link "pu" "opc" "targ" "pcn" -Create a hard link for the node -.Fa targ -into the directory -.Fa opc . -The argument -.Fa pcn -provides the directory entry name for the new link. -.It Fn puffs_node_rename "pu" "src_dir" "src" "pcn_src" "targ_dir" "targ" "pcn_targ" -Rename the node -.Fa src -with the name specified by -.Fa pcn_src -from the directory -.Fa src_dir . -The target directory and target name are given by -.Fa targ_dir -and -.Fa pcn_targ , -respectively. -.Em If -the target node already exists, it is specified by -.Fa targ -and must be replaced atomically. -Otherwise -.Fa targ -is gives as -.Dv NULL . -.Pp -It is legal to replace a directory node by another directory node with -the means of rename if the target directory is empty, otherwise -.Er ENOTEMPTY -should be returned. -All other types can replace all other types. -In case a rename between incompatible types is attempted, the errors -.Er ENOTDIR -or -.Er EISDIR -should be returned, depending on the target type. -.It Fn puffs_node_readdir "pu" "opc" "dent" "readoff" "reslen" "pcr" "eofflag" "cookies" "ncookies" -To read directory entries, -.Fn puffs_node_readdir -is called. -It should store directories as -.Va struct dirent -in the space pointed to by -.Fa dent . -The amount of space available is given by -.Fa reslen -and before returning it should be set to the amount of space -.Em remaining -in the buffer. -The argument -.Fa offset -is used to specify the offset to the directory. -Its intepretation is up to the file system and it should be set to -signal the continuation point when there is no more room for the next -entry in -.Fa dent . -It is most performant to return the maximal amount of directory -entries each call. -It is easiest to generate directory entries by using -.Fn puffs_nextdent , -which also automatically advances the necessary pointers. -.Pp -In case end-of-directory is reached, -.Fa eofflag -should be set to one. -Note that even a new call to readdir may start where -.Fa readoff -points to end-of-directory. -.Pp -If the file system supports file handles, the arguments -.Fa cookies -and -.Fa ncookies -must be filled out. -.Fa cookies -is a vector for offsets corresponding to read offsets. -One cookie should be filled out for each directory entry. -The value of the cookie should equal the offset of the -.Em next -directory entry, i.e., which offset should be passed to readdir for -the first entry read to be the entry following the current one. -.Fa ncookies -is the number of slots for cookies in the cookie vector upon entry to -the function and must be set to the amount of cookies stored in the -vector (i.e., amount of directory entries read) upon exit. -There is always enough space in the cookie vector for the maximal number -of entries that will fit into the directory entry buffer. -For filling out the vector, the helper function -.Fn PUFFS_STORE_DCOOKIE cookies ncookies offset -can be used. -This properly checks against -.Fa cookies -being -.Dv NULL . -Note that -.Fa ncookies -must be initialized to zero before the first call to -.Fn PUFFS_STORE_DCOOKIE . -.It Fn puffs_node_symlink "pu" "opc" "pni" "pcn_src" "va" "link_target" -Create a symbolic link into the directory -.Fa opc -with the name in -.Fa pcn_src -and the initial attributes in -.Fa va . -The argument -.Ar link_target -contains a null-terminated string for the link target. -The created node cookie should be set in -.Fa pni . -.It Fn puffs_node_readlink "pu" "opc" "pcr" "link" "linklen" -Read the target of a symbolic link -.Fa opc . -The result is placed in the buffer pointed to by -.Fa link . -This buffer's length is given in -.Fa linklen -and it must be updated to reflect the real link length. -A terminating nul character should not be put into the buffer and -.Em "must not" -be included in the link length. -.It Fn puffs_node_read "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag" -Read the contents of a file -.Fa opc . -It will gather the data from -.Fa offset -in the file and read the number -.Fa resid -octets. -The buffer is guaranteed to have this much space. -The amount of data requested by -.Fa resid -should be read, except in the case of eof-of-file or an error. -The parameter -.Fa resid -should be set to indicate the amount of request NOT completed. -In the normal case this should be 0. -.It Fn puffs_node_write "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag" -.It Fn puffs_node_write2 "pu" "opc" "buf" "offset" "resid" "pcr" "ioflag" \ -"xflag" -.Fn puffs_node_write -writes data to a file -.Fa opc -at -.Fa offset -and extend the file if necessary. -The number of octets written is indicated by -.Fa resid ; -everything must be written or an error will be generated. -The parameter must be set to indicate the amount of data NOT written. -In case the ioflag -.Dv PUFFS_IO_APPEND -is specified, the data should be appended to the end of the file. -.Fn puffs_node_write2 -serves the same purpose as -.Fn puffs_node_write -with an additional -.Fa xflag -in which -.Dv PUFFS_WRITE_FAF -is set for Fire-And-Forget operations. -.It Fn puffs_node_fallocate "pu" "opc" "pos" "len" -Allocate -.Fa len -bytes of backing store at offset -.Fa pos -for the node referenced by the cookie -.Fa opc . -.It Fn puffs_node_fdiscard "pu" "opc" "pos" "len" -Free -.Fa len -bytes of backing store (creating a hole) at offset -.Fa pos -for the node referenced by the cookie -.Fa opc . -.It Fn puffs_node_print "pu" "opc" -Print information about node. -This is used only for kernel-initiated diagnostic purposes. -.It Fn puffs_node_reclaim "pu" "opc" -The kernel will no longer reference the cookie and resources associated -with it may be freed. -In case the file -.Fa opc -has a link count of zero, it may be safely removed now. -.It Fn puffs_node_reclaim2 "pu" "opc" "nlookup" -Same as -.Fn puffs_node_reclaim -with an addditional argument for the number of lookups that have been done -on the node (Node creation is counted as a lookup). This can be used by the -file system to avoid a race condition, where the kernel sends a reclaim -while it does not have received the reply for a lookup. -If the file system tracks lookup count, and compares to -.Fa nlookup -it can detect this situation and ignore the reclaim. -.Pp -If the file system maps cookies to -.Vt struct puffs_node -then the framework will do that work, and -.Fn puffs_node_reclaim -can be reliabily used without the race condition. -.It Fn puffs_node_abortop "pu" "opc" "pcn" -In case the operation following lookup (e.g., mkdir or remove) is not -executed for some reason, abortop will be issued. -This is useful only for servers which cache state between lookup -and a directory operation and is generally left unimplemented. -.It Fn puffs_node_inactive "pu" "opc" -The node -.Fa opc -has lost its last reference in the kernel. -However, the cookie must still remain valid until -.Fn puffs_node_reclaim -or -.Fn puffs_node_reclaim2 -is called. -.It Fn puffs_setback "pcc" "op" -Issue a "setback" operation which will be handled when the request response -is returned to the kernel. -Currently this can be only called from mmap, open, remove and rmdir. -The valid parameters for -.Ar op -are -.Dv PUFFS_SETBACK_INACT_N1 -and -.Dv PUFFS_SETBACK_INACT_N2 . -These signal that a file system mounted with -.Dv PUFFS_KFLAG_IAONDEMAND -should call the file system inactive method for the specified node. -The node number 1 always means the operation cookie -.Ar opc , -while the node number 2 can be used to specify the second node argument -present in some methods, e.g., remove. -.It Fn puffs_newinfo_setcookie pni cookie -Set cookie for node provided by this method to -.Ar cookie . -.It Fn puffs_newinfo_setvtype pni vtype -Set the type of the newly located node to -.Ar vtype . -This call is valid only for -.Fn lookup -and -.Fn fhtonode . -.It Fn puffs_newinfo_setsize pni size -Set the size of the newly located node to -.Ar size . -If left unset, the value defaults to 0. -This call is valid only for -.Fn lookup -and -.Fn fhtovp . -.It Fn puffs_newinfo_setrdev pni rdev -Set the type of the newly located node to -.Ar vtype . -This call is valid only for -.Fn lookup -and -.Fn fhtovp -producing device type nodes. -.It Fn puffs_newinfo_setva pni vap -Set the attributes for newly created vnode. -This call is valid for -.Fn lookup , -.Fn create , -.Fn mkdir , -.Fn mknod , -and -.Fn symlink , -if -.Fn puffs_init -was called with -.Dv PUFFS_KFLAG_CACHE_FS_TTL -flag set. -.It Fn puffs_newinfo_setvattl pni va_ttl -Set cached attribute time to live for newly created vnode. -This call is valid for -.Fn lookup , -.Fn create , -.Fn mkdir , -.Fn mknod , -and -.Fn symlink , -if -.Fn puffs_init -was called with -.Dv PUFFS_KFLAG_CACHE_FS_TTL -flag set. -.It Fn puffs_newinfo_setcnttl pni cn_ttl -Set cached name time to live for newly created vnode. -This call is valid for -.Fn lookup , -.Fn create , -.Fn mkdir , -.Fn mknod , -and -.Fn symlink , -if -.Fn puffs_init -was called with -.Dv PUFFS_KFLAG_CACHE_FS_TTL -flag set. -.El -.Sh SEE ALSO -.Xr puffs 3 , -.Xr vfsops 9 , -.Xr vnodeops 9 diff --git a/lib/libpuffs/puffs_path.3 b/lib/libpuffs/puffs_path.3 deleted file mode 100644 index ea02bdd7a..000000000 --- a/lib/libpuffs/puffs_path.3 +++ /dev/null @@ -1,125 +0,0 @@ -.\" $NetBSD: puffs_path.3,v 1.4 2009/02/20 14:26:56 pooka Exp $ -.\" -.\" Copyright (c) 2007 Antti Kantee. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd December 27, 2007 -.Dt PUFFS_PATH 3 -.Os -.Sh NAME -.Nm puffs_path -.Nd puffs pathbuilding routines -.Sh LIBRARY -.Lb libpuffs -.Sh SYNOPSIS -.In puffs.h -.Ft int -.Fo pu_pathbuild_fn -.Fa "struct puffs_usermount *pu" "const struct puffs_pathobj *po_dir" -.Fa "const struct puffs_pathobj *po_comp" "size_t offset" -.Fa "struct puffs_pathobj *po_new" -.Fc -.Ft int -.Fo pu_pathtransform_fn -.Fa "struct puffs_usermount *pu" "const struct puffs_pathobj *po_base" -.Fa "const struct puffs_cn *pcn" "struct puffs_pathobj *po_new" -.Fc -.Ft int -.Fo pu_pathcmp_fn -.Fa "struct puffs_usermount *pu" "struct puffs_pathobj *po1" -.Fa "struct puffs_pathobj *po2" "size_t checklen" "int checkprefix" -.Fc -.Ft void -.Fn pu_pathfree_fn "struct puffs_usermount *pu" "struct puffs_pathobj *po" -.Ft int -.Fo pu_namemod_fn -.Fa "struct puffs_usermount *pu" "struct puffs_pathobj *po_dir" -.Fa "struct puffs_cn *pcn" -.Fc -.Ft struct puffs_pathobj * -.Fn puffs_getrootpathobj "struct puffs_usermount *pu" -.Sh DESCRIPTION -The puffs library has the ability to provide full pathnames for backends -which require them. -Normal file systems should be constructed without the file system -node tied to a file name and should not used routines described herein. -An example of a file system where the backend requires filenames is -.Xr mount_psshfs 8 . -.Pp -The features described here are enabled by passing -.Dv PUFFS_FLAG_BUILDPATH -to -.Fn puffs_init . -This facility requires to use puffs nodes to store the contents of the -pathname. -Either the address of the operation cookie must directly be that of the -puffs node, or -.Fn puffs_set_cmap -must be used to set a mapping function from the cookie to the puffs -node associated with the cookie. -Finally, the root node for the file system must be set using -.Fn puffs_setroot -and the root path object retrieved using -.Fn puffs_getrootpathobj -and initialized. -.Pp -There are two different places a filename can be retrieved from. -It is available for each puffs node after the node has been registered -with the framework, i.e. -.Em after -the routine creating the node returns. -In other words, there is a window between the node is created and -when the pathname is available and multithreaded file systems must -take this into account. -The second place where a pathname is available is from the componentname -.Vt struct puffs_pcn -in operations which are passed one. -These can be retrieved using the convenience macros -.Fn PNPATH -and -.Fn PCNPATH -for node and componentname, respectively. -The type of object they return is -.Vt void * . -.Pp -By default the framework manages "regular" filenames, which consist -of directory names separated by "/" and a final component. -If the file system wishes to use pathnames of this format, all it -has to do it enable the feature. -Everything else, including bookkeeping for node and directory renames, -is done by the library. -The callback routines described next provide the ability to build -non-standard pathnames. -A -.Fn pu_foo_fn -callback is set using the -.Fn puffs_set_foo -routine. -.Pp -This manual page is still unfinished. -Please take a number and wait in line. -.Sh SEE ALSO -.Xr puffs 3 , -.Xr puffs_node 3 , -.Xr mount_psshfs 8 , -.Xr mount_sysctlfs 8 diff --git a/lib/libpuffs/puffs_priv.h b/lib/libpuffs/puffs_priv.h deleted file mode 100644 index 8e08e79e7..000000000 --- a/lib/libpuffs/puffs_priv.h +++ /dev/null @@ -1,278 +0,0 @@ -/* $NetBSD: puffs_priv.h,v 1.45 2012/04/18 00:57:22 manu Exp $ */ - -/* - * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _PUFFS_PRIVATE_H_ -#define _PUFFS_PRIVATE_H_ - -#include -#include - -#if !defined(__minix) -#include -#endif /* !defined(__minix) */ -#include -#include - -#if !defined(__minix) -extern pthread_mutex_t pu_lock; -#define PU_LOCK() pthread_mutex_lock(&pu_lock) -#define PU_UNLOCK() pthread_mutex_unlock(&pu_lock) -#else -#define PU_LOCK() /* nothing */ -#define PU_UNLOCK() /* nothing */ -#endif /* !defined(__minix) */ - -#define PU_CMAP(pu, c) (pu->pu_cmap ? pu->pu_cmap(pu,c) : (struct puffs_node*)c) - -struct puffs_framectrl { - puffs_framev_readframe_fn rfb; - puffs_framev_writeframe_fn wfb; - puffs_framev_cmpframe_fn cmpfb; - puffs_framev_gotframe_fn gotfb; - puffs_framev_fdnotify_fn fdnotfn; -}; - -struct puffs_fctrl_io { - struct puffs_framectrl *fctrl; - - int io_fd; - int stat; - - int rwait; - int wwait; - - struct puffs_framebuf *cur_in; - - TAILQ_HEAD(, puffs_framebuf) snd_qing; /* queueing to be sent */ - TAILQ_HEAD(, puffs_framebuf) res_qing; /* q'ing for rescue */ - LIST_HEAD(, puffs_fbevent) ev_qing; /* q'ing for events */ - - LIST_ENTRY(puffs_fctrl_io) fio_entries; -}; -#define FIO_WR 0x01 -#define FIO_WRGONE 0x02 -#define FIO_RDGONE 0x04 -#define FIO_DEAD 0x08 -#define FIO_ENABLE_R 0x10 -#define FIO_ENABLE_W 0x20 - -#define FIO_EN_WRITE(fio) \ - (!(fio->stat & FIO_WR) \ - && ((!TAILQ_EMPTY(&fio->snd_qing) \ - && (fio->stat & FIO_ENABLE_W)) \ - || fio->wwait)) - -#define FIO_RM_WRITE(fio) \ - ((fio->stat & FIO_WR) \ - && (((TAILQ_EMPTY(&fio->snd_qing) \ - || (fio->stat & FIO_ENABLE_W) == 0)) \ - && (fio->wwait == 0))) - - -/* - * usermount: describes one file system instance - */ -struct puffs_usermount { - struct puffs_ops pu_ops; - - int pu_fd; - size_t pu_maxreqlen; - - uint32_t pu_flags; - int pu_cc_stackshift; - - ucontext_t pu_mainctx; -#define PUFFS_CCMAXSTORE 32 - int pu_cc_nstored; - - int pu_kq; - int pu_state; -#define PU_STATEMASK 0x00ff -#define PU_INLOOP 0x0100 -#define PU_ASYNCFD 0x0200 -#define PU_HASKQ 0x0400 -#define PU_PUFFSDAEMON 0x0800 -#define PU_MAINRESTORE 0x1000 -#define PU_DONEXIT 0x2000 -#define PU_SETSTATE(pu, s) (pu->pu_state = (s) | (pu->pu_state & ~PU_STATEMASK)) -#define PU_SETSFLAG(pu, s) (pu->pu_state |= (s)) -#define PU_CLRSFLAG(pu, s) \ - (pu->pu_state = ((pu->pu_state & ~(s)) | (pu->pu_state & PU_STATEMASK))) - int pu_dpipe[2]; - - struct puffs_node *pu_pn_root; - - LIST_HEAD(, puffs_node) pu_pnodelst; -#if defined(__minix) - LIST_HEAD(, puffs_node) pu_pnode_removed_lst; -#endif /* defined(__minix) */ - - LIST_HEAD(, puffs_cc) pu_ccmagazin; - TAILQ_HEAD(, puffs_cc) pu_lazyctx; - TAILQ_HEAD(, puffs_cc) pu_sched; - - pu_cmap_fn pu_cmap; - - pu_pathbuild_fn pu_pathbuild; - pu_pathtransform_fn pu_pathtransform; - pu_pathcmp_fn pu_pathcmp; - pu_pathfree_fn pu_pathfree; - pu_namemod_fn pu_namemod; - - pu_errnotify_fn pu_errnotify; - - pu_prepost_fn pu_oppre; - pu_prepost_fn pu_oppost; - - struct puffs_framectrl pu_framectrl[2]; -#define PU_FRAMECTRL_FS 0 -#define PU_FRAMECTRL_USER 1 - LIST_HEAD(, puffs_fctrl_io) pu_ios; - LIST_HEAD(, puffs_fctrl_io) pu_ios_rmlist; - struct kevent *pu_evs; - size_t pu_nevs; - - puffs_ml_loop_fn pu_ml_lfn; - struct timespec pu_ml_timeout; - struct timespec *pu_ml_timep; - - struct puffs_kargs *pu_kargp; - - uint64_t pu_nextreq; - void *pu_privdata; -}; - -/* call context */ - -struct puffs_cc; -typedef void (*puffs_ccfunc)(struct puffs_cc *); - -struct puffs_cc { - struct puffs_usermount *pcc_pu; - struct puffs_framebuf *pcc_pb; - - /* real cc */ - union { - struct { - ucontext_t uc; /* "continue" */ - ucontext_t uc_ret; /* "yield" */ - } real; - struct { - puffs_ccfunc func; - void *farg; - } fake; - } pcc_u; - - pid_t pcc_pid; - lwpid_t pcc_lid; - - int pcc_flags; - - TAILQ_ENTRY(puffs_cc) pcc_schedent; - LIST_ENTRY(puffs_cc) pcc_rope; -}; -#define pcc_uc pcc_u.real.uc -#define pcc_uc_ret pcc_u.real.uc_ret -#define pcc_func pcc_u.fake.func -#define pcc_farg pcc_u.fake.farg -#define PCC_DONE 0x01 -#define PCC_BORROWED 0x02 -#define PCC_HASCALLER 0x04 -#define PCC_MLCONT 0x08 - -struct puffs_newinfo { - void **pni_cookie; - enum vtype *pni_vtype; - voff_t *pni_size; - dev_t *pni_rdev; - struct vattr *pni_va; - struct timespec *pni_va_ttl; - struct timespec *pni_cn_ttl; -}; - -#define PUFFS_MAKEKCRED(to, from) \ - /*LINTED: tnilxnaht, the cast is ok */ \ - const struct puffs_kcred *to = (const void *)from -#define PUFFS_MAKECRED(to, from) \ - /*LINTED: tnilxnaht, the cast is ok */ \ - const struct puffs_cred *to = (const void *)from -#define PUFFS_KCREDTOCRED(to, from) \ - /*LINTED: tnilxnaht, the cast is ok */ \ - to = (void *)from - -__BEGIN_DECLS - -void puffs__framev_input(struct puffs_usermount *, struct puffs_framectrl *, - struct puffs_fctrl_io *); -int puffs__framev_output(struct puffs_usermount *, struct puffs_framectrl*, - struct puffs_fctrl_io *); -void puffs__framev_exit(struct puffs_usermount *); -void puffs__framev_readclose(struct puffs_usermount *, - struct puffs_fctrl_io *, int); -void puffs__framev_writeclose(struct puffs_usermount *, - struct puffs_fctrl_io *, int); -void puffs__framev_notify(struct puffs_fctrl_io *, int); -void *puffs__framebuf_getdataptr(struct puffs_framebuf *); -int puffs__framev_addfd_ctrl(struct puffs_usermount *, int, int, - struct puffs_framectrl *); -void puffs__framebuf_moveinfo(struct puffs_framebuf *, - struct puffs_framebuf *); - -void puffs__theloop(struct puffs_cc *); -void puffs__ml_dispatch(struct puffs_usermount *, struct puffs_framebuf *); - -int puffs__cc_create(struct puffs_usermount *, puffs_ccfunc, - struct puffs_cc **); -void puffs__cc_cont(struct puffs_cc *); -void puffs__cc_destroy(struct puffs_cc *, int); -void puffs__cc_setcaller(struct puffs_cc *, pid_t, lwpid_t); -void puffs__goto(struct puffs_cc *); -int puffs__cc_savemain(struct puffs_usermount *); -int puffs__cc_restoremain(struct puffs_usermount *); -void puffs__cc_exit(struct puffs_usermount *); - -int puffs__fsframe_read(struct puffs_usermount *, struct puffs_framebuf *, - int, int *); -int puffs__fsframe_write(struct puffs_usermount *, struct puffs_framebuf *, - int, int *); -int puffs__fsframe_cmp(struct puffs_usermount *, struct puffs_framebuf *, - struct puffs_framebuf *, int *); -void puffs__fsframe_gotframe(struct puffs_usermount *, - struct puffs_framebuf *); - -uint64_t puffs__nextreq(struct puffs_usermount *pu); - -#if defined(__minix) -int lpuffs_pump(void); -void lpuffs_init(struct puffs_usermount *); -void lpuffs_debug(const char *format, ...) - __attribute__((__format__(__printf__, 1, 2))); -#endif /* defined(__minix) */ - -__END_DECLS - -#endif /* _PUFFS_PRIVATE_H_ */ diff --git a/lib/libpuffs/puffsdump.h b/lib/libpuffs/puffsdump.h deleted file mode 100644 index 856c5eb1e..000000000 --- a/lib/libpuffs/puffsdump.h +++ /dev/null @@ -1,68 +0,0 @@ -/* $NetBSD: puffsdump.h,v 1.15 2010/07/11 12:29:08 pooka Exp $ */ - -/* - * Copyright (c) 2006 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the Ulla Tuominen Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _PUFFSDUMP_H_ -#define _PUFFSDUMP_H_ - -/* - * Note for callers outside of libpuffs: these are to be used only - * for debug builds. Interfaces are not guaranteed to remain stable. - */ - -#include - -void puffsdump_req(struct puffs_req *); -void puffsdump_rv(struct puffs_req *); -void puffsdump_cookie(puffs_cookie_t, const char *); -void puffsdump_cn(struct puffs_kcn *); - -void puffsdump_readwrite(struct puffs_req *); -void puffsdump_readwrite_rv(struct puffs_req *); -void puffsdump_readdir(struct puffs_req *); -void puffsdump_readdir_rv(struct puffs_req *); -void puffsdump_lookup(struct puffs_req *); -void puffsdump_lookup_rv(struct puffs_req *); -void puffsdump_create(struct puffs_req *); -void puffsdump_create_rv(struct puffs_req *); -void puffsdump_open(struct puffs_req *); - -void puffsdump_attr(struct puffs_req *); -void puffsdump_targ(struct puffs_req *); - -extern const char *puffsdump_vfsop_revmap[]; -extern const char *puffsdump_vnop_revmap[]; -extern const char *puffsdump_errnot_revmap[]; -extern const char *puffsdump_flush_revmap[]; - -extern size_t puffsdump_vfsop_count; -extern size_t puffsdump_vnop_count; -extern size_t puffsdump_errnot_count; -extern size_t puffsdump_flush_count; - -#endif /* _PUFFSDUMP_H_ */ diff --git a/lib/libpuffs/requests.c b/lib/libpuffs/requests.c deleted file mode 100644 index e33fe017b..000000000 --- a/lib/libpuffs/requests.c +++ /dev/null @@ -1,239 +0,0 @@ -/* $NetBSD: requests.c,v 1.24 2013/01/23 20:22:34 riastradh Exp $ */ - -/* - * Copyright (c) 2007 Antti Kantee. All Rights Reserved. - * - * Development of this software was supported by the - * Research Foundation of Helsinki University of Technology - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: requests.c,v 1.24 2013/01/23 20:22:34 riastradh Exp $"); -#endif /* !lint */ - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -/* - * Read a frame from the upstream provider. First read the frame - * length and after this read the actual contents. Yes, optimize - * me some day. - */ -/*ARGSUSED*/ -int -puffs__fsframe_read(struct puffs_usermount *pu, struct puffs_framebuf *pb, - int fd, int *done) -{ - struct putter_hdr phdr; - void *win; - size_t howmuch, winlen, curoff; - ssize_t n; - int lenstate; - - /* How much to read? */ - the_next_level: - curoff = puffs_framebuf_telloff(pb); - if (curoff < sizeof(struct putter_hdr)) { - howmuch = sizeof(struct putter_hdr) - curoff; - lenstate = 1; - } else { - puffs_framebuf_getdata_atoff(pb, 0, &phdr, sizeof(phdr)); - /*LINTED*/ - howmuch = phdr.pth_framelen - curoff; - lenstate = 0; - } - - if (puffs_framebuf_reserve_space(pb, howmuch) == -1) - return errno; - - /* Read contents */ - while (howmuch) { - winlen = howmuch; - curoff = puffs_framebuf_telloff(pb); - if (puffs_framebuf_getwindow(pb, curoff, &win, &winlen) == -1) - return errno; - n = read(fd, win, winlen); - switch (n) { - case 0: - return ECONNRESET; - case -1: - if (errno == EAGAIN) - return 0; - return errno; - default: - howmuch -= n; - puffs_framebuf_seekset(pb, curoff + n); - break; - } - } - - if (lenstate) - goto the_next_level; - - puffs_framebuf_seekset(pb, 0); - *done = 1; - return 0; -} - -/* - * Write a frame upstream - */ -/*ARGSUSED*/ -int -puffs__fsframe_write(struct puffs_usermount *pu, struct puffs_framebuf *pb, - int fd, int *done) -{ - void *win; - uint64_t flen; - size_t winlen, howmuch, curoff; - ssize_t n; - int rv; - - /* - * Finalize it if we haven't written anything yet (or we're still - * attempting to write the first byte) - * - * XXX: this shouldn't be here - */ - if (puffs_framebuf_telloff(pb) == 0) { - struct puffs_req *preq; - - winlen = sizeof(struct puffs_req); - rv = puffs_framebuf_getwindow(pb, 0, (void *)&preq, &winlen); - if (rv == -1) - return errno; - preq->preq_pth.pth_framelen = flen = preq->preq_buflen; - } else { - struct putter_hdr phdr; - - puffs_framebuf_getdata_atoff(pb, 0, &phdr, sizeof(phdr)); - flen = phdr.pth_framelen; - } - - /* - * Then write it. Chances are if we are talking to the kernel it'll - * just shlosh in all at once, but if we're e.g. talking to the - * network it might take a few tries. - */ - /*LINTED*/ - howmuch = flen - puffs_framebuf_telloff(pb); - - while (howmuch) { - winlen = howmuch; - curoff = puffs_framebuf_telloff(pb); - if (puffs_framebuf_getwindow(pb, curoff, &win, &winlen) == -1) - return errno; - - /* - * XXX: we know from the framebuf implementation that we - * will always managed to map the entire window. But if - * that changes, this will catch it. Then we can do stuff - * iov stuff instead. - */ - assert(winlen == howmuch); - - /* XXX: want NOSIGNAL if writing to a pipe */ -#if 0 - n = send(fd, win, winlen, MSG_NOSIGNAL); -#else - n = write(fd, win, winlen); -#endif - switch (n) { - case 0: - return ECONNRESET; - case -1: - if (errno == EAGAIN) - return 0; - return errno; - default: - howmuch -= n; - puffs_framebuf_seekset(pb, curoff + n); - break; - } - } - - *done = 1; - return 0; -} - -/* - * Compare if "pb1" is a response to a previously sent frame pb2. - * More often than not "pb1" is not a response to anything but - * rather a fresh request from the kernel. - */ -/*ARGSUSED*/ -int -puffs__fsframe_cmp(struct puffs_usermount *pu, - struct puffs_framebuf *pb1, struct puffs_framebuf *pb2, int *notresp) -{ - struct puffs_req *preq1, *preq2; - size_t winlen; - int rv; - - /* map incoming preq */ - winlen = sizeof(struct puffs_req); - rv = puffs_framebuf_getwindow(pb1, 0, (void *)&preq1, &winlen); - assert(rv == 0); /* frames are always at least puffs_req in size */ - assert(winlen == sizeof(struct puffs_req)); - - /* - * Check if this is not a response in this slot. That's the - * likely case. - */ - if ((preq1->preq_opclass & PUFFSOPFLAG_ISRESPONSE) == 0) { - *notresp = 1; - return 0; - } - - /* map second preq */ - winlen = sizeof(struct puffs_req); - rv = puffs_framebuf_getwindow(pb2, 0, (void *)&preq2, &winlen); - assert(rv == 0); /* frames are always at least puffs_req in size */ - assert(winlen == sizeof(struct puffs_req)); - - /* then compare: resid equal? */ - return preq1->preq_id != preq2->preq_id; -} - -void -puffs__fsframe_gotframe(struct puffs_usermount *pu, struct puffs_framebuf *pb) -{ - - puffs_framebuf_seekset(pb, 0); - puffs__ml_dispatch(pu, pb); -} diff --git a/lib/libpuffs/shlib_version b/lib/libpuffs/shlib_version deleted file mode 100644 index 15bf95400..000000000 --- a/lib/libpuffs/shlib_version +++ /dev/null @@ -1,4 +0,0 @@ -# $NetBSD: shlib_version,v 1.5 2010/05/21 10:50:52 pooka Exp $ -# -major=2 -minor=0 diff --git a/lib/libpuffs/subr.c b/lib/libpuffs/subr.c deleted file mode 100644 index 08d0ecd76..000000000 --- a/lib/libpuffs/subr.c +++ /dev/null @@ -1,321 +0,0 @@ -/* $NetBSD: subr.c,v 1.27 2011/02/17 17:55:36 pooka Exp $ */ - -/* - * Copyright (c) 2006 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: subr.c,v 1.27 2011/02/17 17:55:36 pooka Exp $"); -#endif /* !lint */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "puffs_priv.h" - -int -puffs_gendotdent(struct dirent **dent, ino_t id, int dotdot, size_t *reslen) -{ - const char *name; - - assert(dotdot == 0 || dotdot == 1); - name = dotdot == 0 ? "." : ".."; - - return puffs_nextdent(dent, name, id, DT_DIR, reslen); -} - -int -puffs_nextdent(struct dirent **dent, const char *name, ino_t id, uint8_t dtype, - size_t *reslen) -{ - struct dirent *d = *dent; - - /* check if we have enough room for our dent-aligned dirent */ - if (_DIRENT_RECLEN(d, strlen(name)) > *reslen) - return 0; - - d->d_fileno = id; - d->d_type = dtype; - d->d_namlen = (uint16_t)strlen(name); - (void)memcpy(&d->d_name, name, (size_t)d->d_namlen); - d->d_name[d->d_namlen] = '\0'; - d->d_reclen = (uint16_t)_DIRENT_SIZE(d); - - *reslen -= d->d_reclen; - *dent = _DIRENT_NEXT(d); - - return 1; -} - -/*ARGSUSED*/ -int -puffs_fsnop_unmount(struct puffs_usermount *dontuse1, int dontuse2) -{ - - /* would you like to see puffs rule again, my friend? */ - return 0; -} - -/*ARGSUSED*/ -int -puffs_fsnop_sync(struct puffs_usermount *dontuse1, int dontuse2, - const struct puffs_cred *dontuse3) -{ - - return 0; -} - -/*ARGSUSED*/ -int -puffs_fsnop_statvfs(struct puffs_usermount *dontuse1, struct statvfs *sbp) -{ - - sbp->f_bsize = sbp->f_frsize = sbp->f_iosize = DEV_BSIZE; - - sbp->f_bfree=sbp->f_bavail=sbp->f_bresvd=sbp->f_blocks = (fsblkcnt_t)0; - sbp->f_ffree=sbp->f_favail=sbp->f_fresvd=sbp->f_files = (fsfilcnt_t)0; - - sbp->f_namemax = MAXNAMLEN; - - return 0; -} - -/*ARGSUSED3*/ -int -puffs_genfs_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, - struct vattr *va, const struct puffs_cred *pcr) -{ - struct puffs_node *pn = PU_CMAP(pu, opc); - - memcpy(va, &pn->pn_va, sizeof(struct vattr)); - return 0; -} - -/* - * Just put the node, don't do anything else. Don't use this if - * your fs needs more cleanup. - */ -/*ARGSUSED2*/ -int -puffs_genfs_node_reclaim(struct puffs_usermount *pu, puffs_cookie_t opc) -{ - - puffs_pn_put(PU_CMAP(pu, opc)); - - return 0; -} - -/* - * Just a wrapper to make calling the above nicer without having to pass - * NULLs from application code - */ -void -puffs_zerostatvfs(struct statvfs *sbp) -{ - - puffs_fsnop_statvfs(NULL, sbp); -} - -/* - * Set vattr values for those applicable (i.e. not PUFFS_VNOVAL). - */ -void -puffs_setvattr(struct vattr *vap, const struct vattr *sva) -{ - -#define SETIFVAL(a, t) if (sva->a != (t)PUFFS_VNOVAL) vap->a = sva->a - if (sva->va_type != VNON) - vap->va_type = sva->va_type; - SETIFVAL(va_mode, mode_t); - SETIFVAL(va_nlink, nlink_t); - SETIFVAL(va_uid, uid_t); - SETIFVAL(va_gid, gid_t); - SETIFVAL(va_fsid, dev_t); - SETIFVAL(va_size, u_quad_t); - SETIFVAL(va_fileid, ino_t); - SETIFVAL(va_blocksize, long); - SETIFVAL(va_atime.tv_sec, time_t); - SETIFVAL(va_ctime.tv_sec, time_t); - SETIFVAL(va_mtime.tv_sec, time_t); - SETIFVAL(va_birthtime.tv_sec, time_t); - SETIFVAL(va_atime.tv_nsec, long); - SETIFVAL(va_ctime.tv_nsec, long); - SETIFVAL(va_mtime.tv_nsec, long); - SETIFVAL(va_birthtime.tv_nsec, long); - SETIFVAL(va_gen, u_long); - SETIFVAL(va_flags, u_long); - SETIFVAL(va_rdev, dev_t); - SETIFVAL(va_bytes, u_quad_t); -#undef SETIFVAL - /* ignore va->va_vaflags */ -} - -void -puffs_vattr_null(struct vattr *vap) -{ - - vap->va_type = VNON; - - /* - * Assign individually so that it is safe even if size and - * sign of each member are varied. - */ - vap->va_mode = (mode_t)PUFFS_VNOVAL; - vap->va_nlink = (nlink_t)PUFFS_VNOVAL; - vap->va_uid = (uid_t)PUFFS_VNOVAL; - vap->va_gid = (gid_t)PUFFS_VNOVAL; - vap->va_fsid = (dev_t)PUFFS_VNOVAL; - vap->va_fileid = (ino_t)PUFFS_VNOVAL; - vap->va_size = (u_quad_t)PUFFS_VNOVAL; - vap->va_blocksize = sysconf(_SC_PAGESIZE); - vap->va_atime.tv_sec = - vap->va_mtime.tv_sec = - vap->va_ctime.tv_sec = - vap->va_birthtime.tv_sec = PUFFS_VNOVAL; - vap->va_atime.tv_nsec = - vap->va_mtime.tv_nsec = - vap->va_ctime.tv_nsec = - vap->va_birthtime.tv_nsec = PUFFS_VNOVAL; - vap->va_rdev = (dev_t)PUFFS_VNOVAL; - vap->va_bytes = (u_quad_t)PUFFS_VNOVAL; - - vap->va_flags = 0; - vap->va_gen = 0; - vap->va_vaflags = 0; -} - -static int vdmap[] = { - DT_UNKNOWN, /* VNON */ - DT_REG, /* VREG */ - DT_DIR, /* VDIR */ - DT_BLK, /* VBLK */ - DT_CHR, /* VCHR */ - DT_LNK, /* VLNK */ - DT_SOCK, /* VSUCK*/ - DT_FIFO, /* VFIFO*/ - DT_UNKNOWN /* VBAD */ -}; -/* XXX: DT_WHT ? */ -int -puffs_vtype2dt(enum vtype vt) -{ - - if ((int)vt >= VNON && vt < (sizeof(vdmap)/sizeof(vdmap[0]))) - return vdmap[vt]; - - return DT_UNKNOWN; -} - -enum vtype -puffs_mode2vt(mode_t mode) -{ - - switch (mode & S_IFMT) { - case S_IFIFO: - return VFIFO; - case S_IFCHR: - return VCHR; - case S_IFDIR: - return VDIR; - case S_IFBLK: - return VBLK; - case S_IFREG: - return VREG; - case S_IFLNK: - return VLNK; - case S_IFSOCK: - return VSOCK; - default: - return VBAD; /* XXX: not really true, but ... */ - } -} - -void -puffs_stat2vattr(struct vattr *va, const struct stat *sb) -{ - - va->va_type = puffs_mode2vt(sb->st_mode); - va->va_mode = sb->st_mode; - va->va_nlink = sb->st_nlink; - va->va_uid = sb->st_uid; - va->va_gid = sb->st_gid; - va->va_fsid = sb->st_dev; - va->va_fileid = sb->st_ino; - va->va_size = sb->st_size; - va->va_blocksize = sb->st_blksize; - va->va_atime = sb->st_atimespec; - va->va_ctime = sb->st_ctimespec; - va->va_mtime = sb->st_mtimespec; - va->va_birthtime = sb->st_birthtimespec; - va->va_gen = sb->st_gen; - va->va_flags = sb->st_flags; - va->va_rdev = sb->st_rdev; - va->va_bytes = sb->st_blocks << DEV_BSHIFT; - va->va_filerev = 0; - va->va_vaflags = 0; -} - -mode_t -puffs_addvtype2mode(mode_t mode, enum vtype type) -{ - - switch (type) { - case VCHR: - mode |= S_IFCHR; - break; - case VBLK: - mode |= S_IFBLK; - break; - case VSOCK: - mode |= S_IFSOCK; - break; - case VFIFO: - mode |= S_IFIFO; - break; - case VREG: - mode |= S_IFREG; - break; - case VLNK: - mode |= S_IFLNK; - break; - case VDIR: - mode |= S_IFDIR; - break; - default: - break; - } - - return mode; -} diff --git a/lib/libpuffs/suspend.c b/lib/libpuffs/suspend.c deleted file mode 100644 index 9a1ede2e6..000000000 --- a/lib/libpuffs/suspend.c +++ /dev/null @@ -1,49 +0,0 @@ -/* $NetBSD: suspend.c,v 1.10 2009/12/05 12:13:08 pooka Exp $ */ - -/* - * Copyright (c) 2007 Antti Kantee. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if !defined(lint) -__RCSID("$NetBSD: suspend.c,v 1.10 2009/12/05 12:13:08 pooka Exp $"); -#endif /* !lint */ - -/* - * File system suspension - */ - -#include - -#include -#include - -/*ARGSUSED*/ -int -puffs_fs_suspend(struct puffs_usermount *pu) -{ - - /* used to be, no longer is. just return error to avoid ABI bump */ - return EOPNOTSUPP; -} diff --git a/lib/librmt/Makefile b/lib/librmt/Makefile deleted file mode 100644 index 9addd02b0..000000000 --- a/lib/librmt/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# $NetBSD: Makefile,v 1.9 2007/05/28 12:06:21 tls Exp $ - -USE_FORT?= yes # network protocol library - -NOPIC= # defined -NOPROFILE= # defined - -LIB= rmt -SRCS= rmtlib.c -MAN= rmtops.3 - -.if defined(__MINIX) -# rmtlib.c:451:50: error: format specifies type 'size_t' (aka 'unsigned long') \ -# but the argument has type 'size_t' (aka 'unsigned int') [-Werror,-Wformat] -WARNS=0 -CFLAGS+=-Wno-format -.endif - -.if !defined(__MINIX) -CPPFLAGS+= -D_REENTRANT -.endif # !defined(__MINIX) - -.include diff --git a/lib/librmt/README b/lib/librmt/README deleted file mode 100644 index 9191077c7..000000000 --- a/lib/librmt/README +++ /dev/null @@ -1,20 +0,0 @@ -# $NetBSD: README,v 1.2 1998/01/09 04:12:19 perry Exp $ - -README - -This is the remote mag tape library. It allows a program that uses -Unix system calls to transparently use a file (usually a tape drive) on -another system via /etc/rmt, simply by including . It is -particularly useful with tar and dd, and is supplied with GNU tar. - -This package has evolved somewhat over the years. My thanks to the -people who did most of the original work, and those who've contributed -bug fixes; appropriate credit is in the man page and source files. - -Enjoy, - -Arnold Robbins -Emory U. Computing Center -arnold@emoryu1.cc.emory.edu -gatech!emoryu1!arnold -+1 404 727 7636 diff --git a/lib/librmt/pathnames.h b/lib/librmt/pathnames.h deleted file mode 100644 index ec1757863..000000000 --- a/lib/librmt/pathnames.h +++ /dev/null @@ -1,30 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.2 2008/05/29 14:51:25 mrg Exp $ */ - -/* - * Copyright (c) 1998 Matthew R. Green - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define _PATH_RSH "/usr/bin/rsh" -#define _PATH_RMT "/etc/rmt" diff --git a/lib/librmt/rmtlib.c b/lib/librmt/rmtlib.c deleted file mode 100644 index cadeab398..000000000 --- a/lib/librmt/rmtlib.c +++ /dev/null @@ -1,896 +0,0 @@ -/* $NetBSD: rmtlib.c,v 1.26 2012/03/21 10:10:37 matt Exp $ */ - -/* - * rmt --- remote tape emulator subroutines - * - * Originally written by Jeff Lee, modified some by Arnold Robbins - * - * WARNING: The man page rmt(8) for /etc/rmt documents the remote mag - * tape protocol which rdump and rrestore use. Unfortunately, the man - * page is *WRONG*. The author of the routines I'm including originally - * wrote his code just based on the man page, and it didn't work, so he - * went to the rdump source to figure out why. The only thing he had to - * change was to check for the 'F' return code in addition to the 'E', - * and to separate the various arguments with \n instead of a space. I - * personally don't think that this is much of a problem, but I wanted to - * point it out. - * -- Arnold Robbins - * - * Redone as a library that can replace open, read, write, etc, by - * Fred Fish, with some additional work by Arnold Robbins. - */ - -/* - * MAXUNIT --- Maximum number of remote tape file units - * - * READ --- Return the number of the read side file descriptor - * WRITE --- Return the number of the write side file descriptor - */ - -#include -__RCSID("$NetBSD: rmtlib.c,v 1.26 2012/03/21 10:10:37 matt Exp $"); - -#define RMTIOCTL 1 -/* #define USE_REXEC 1 */ /* rexec code courtesy of Dan Kegel, srs!dan */ - -#include -#include - -#ifdef RMTIOCTL -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef USE_REXEC -#include -#endif - -#define __RMTLIB_PRIVATE -#include /* get prototypes for remapped functions */ - -#include "pathnames.h" - -static int _rmt_close(int); -static int _rmt_ioctl(int, unsigned long, void *); -static off_t _rmt_lseek(int, off_t, int); -static int _rmt_open(const char *, int, int); -static ssize_t _rmt_read(int, void *, size_t); -static ssize_t _rmt_write(int, const void *, size_t); -static int command(int, const char *); -static int remdev(const char *); -static void rmtabort(int); -static int status(int); - - -#define BUFMAGIC 64 /* a magic number for buffer sizes */ -#define MAXUNIT 4 - -#define READ(fd) (Ctp[fd][0]) -#define WRITE(fd) (Ptc[fd][1]) - -static int Ctp[MAXUNIT][2] = { {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }; -static int Ptc[MAXUNIT][2] = { {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1} }; - - -/* - * rmtabort --- close off a remote tape connection - */ -static void -rmtabort(int fildes) -{ - - close(READ(fildes)); - close(WRITE(fildes)); - READ(fildes) = -1; - WRITE(fildes) = -1; -} - - -/* - * command --- attempt to perform a remote tape command - */ -static int -command(int fildes, const char *buf) -{ - size_t blen; - sig_t pstat; - - _DIAGASSERT(buf != NULL); - -/* - * save current pipe status and try to make the request - */ - - blen = strlen(buf); - pstat = signal(SIGPIPE, SIG_IGN); - if ((size_t)write(WRITE(fildes), buf, blen) == blen) { - signal(SIGPIPE, pstat); - return 0; - } - -/* - * something went wrong. close down and go home - */ - - signal(SIGPIPE, pstat); - rmtabort(fildes); - - errno = EIO; - return -1; -} - - -/* - * status --- retrieve the status from the pipe - */ -static int -status(int fildes) -{ - int i; - char c, *cp; - char buffer[BUFMAGIC]; - -/* - * read the reply command line - */ - - for (i = 0, cp = buffer; i < BUFMAGIC; i++, cp++) { - if (read(READ(fildes), cp, 1) != 1) { - rmtabort(fildes); - errno = EIO; - return -1; - } - if (*cp == '\n') { - *cp = 0; - break; - } - } - - if (i == BUFMAGIC) { - rmtabort(fildes); - errno = EIO; - return -1; - } - -/* - * check the return status - */ - - for (cp = buffer; *cp; cp++) - if (*cp != ' ') - break; - - if (*cp == 'E' || *cp == 'F') { - errno = atoi(cp + 1); - while (read(READ(fildes), &c, 1) == 1) - if (c == '\n') - break; - - if (*cp == 'F') - rmtabort(fildes); - - return -1; - } - -/* - * check for mis-synced pipes - */ - - if (*cp != 'A') { - rmtabort(fildes); - errno = EIO; - return -1; - } - - return atoi(cp + 1); -} - - -#ifdef USE_REXEC -/* - * _rmt_rexec - * - * execute /etc/rmt on a remote system using rexec(). - * Return file descriptor of bidirectional socket for stdin and stdout - * If username is NULL, or an empty string, uses current username. - * - * ADR: By default, this code is not used, since it requires that - * the user have a .netrc file in his/her home directory, or that the - * application designer be willing to have rexec prompt for login and - * password info. This may be unacceptable, and .rhosts files for use - * with rsh are much more common on BSD systems. - */ - -static int _rmt_rexec(const char *, const char *); - -static int -_rmt_rexec(const char *host, const char *user) -{ - struct servent *rexecserv; - - _DIAGASSERT(host != NULL); - /* user may be NULL */ - - rexecserv = getservbyname("exec", "tcp"); - if (rexecserv == NULL) - errx(1, "exec/tcp: service not available."); - if ((user != NULL) && *user == '\0') - user = NULL; - return rexec(&host, rexecserv->s_port, user, NULL, - "/etc/rmt", NULL); -} -#endif /* USE_REXEC */ - - -/* - * _rmt_open --- open a magtape device on system specified, as given user - * - * file name has the form [user@]system:/dev/???? -#ifdef COMPAT - * file name has the form system[.user]:/dev/???? -#endif - */ - -#define MAXHOSTLEN 257 /* BSD allows very long host names... */ - -static int -/*ARGSUSED*/ -_rmt_open(const char *path, int oflag, int mode) -{ - int i; - char buffer[BUFMAGIC]; - char host[MAXHOSTLEN]; - char device[BUFMAGIC]; - char login[BUFMAGIC]; - char *sys, *dev, *user; - const char *rshpath, *rsh; - - _DIAGASSERT(path != NULL); - - sys = host; - dev = device; - user = login; - -/* - * first, find an open pair of file descriptors - */ - - for (i = 0; i < MAXUNIT; i++) - if (READ(i) == -1 && WRITE(i) == -1) - break; - - if (i == MAXUNIT) { - errno = EMFILE; - return -1; - } - -/* - * pull apart system and device, and optional user - * don't munge original string - * if COMPAT is defined, also handle old (4.2) style person.site notation. - */ - - while (*path != '@' -#ifdef COMPAT - && *path != '.' -#endif - && *path != ':') { - *sys++ = *path++; - } - *sys = '\0'; - path++; - - if (*(path - 1) == '@') { - (void)strncpy(user, host, sizeof(login) - 1); - /* saw user part of user@host */ - sys = host; /* start over */ - while (*path != ':') { - *sys++ = *path++; - } - *sys = '\0'; - path++; - } -#ifdef COMPAT - else if (*(path - 1) == '.') { - while (*path != ':') { - *user++ = *path++; - } - *user = '\0'; - path++; - } -#endif - else - *user = '\0'; - - while (*path) { - *dev++ = *path++; - } - *dev = '\0'; - -#ifdef USE_REXEC -/* - * Execute the remote command using rexec - */ - READ(i) = WRITE(i) = _rmt_rexec(host, login); - if (READ(i) < 0) - return -1; -#else -/* - * setup the pipes for the 'rsh' command and fork - */ - - if (pipe(Ptc[i]) == -1 || pipe(Ctp[i]) == -1) - return -1; - - switch (fork()) { - case -1: - return -1; - - case 0: - close(0); - dup(Ptc[i][0]); - close(Ptc[i][0]); close(Ptc[i][1]); - close(1); - dup(Ctp[i][1]); - close(Ctp[i][0]); close(Ctp[i][1]); - (void) setuid(getuid()); - (void) setgid(getgid()); - - if ((rshpath = getenv("RCMD_CMD")) == NULL) - rshpath = _PATH_RSH; - if ((rsh = strrchr(rshpath, '/')) == NULL) - rsh = rshpath; - else - rsh++; - - if (*login) { - execl(rshpath, rsh, host, "-l", login, _PATH_RMT, NULL); - } else { - execl(rshpath, rsh, host, _PATH_RMT, NULL); - } - -/* - * bad problems if we get here - */ - - err(1, "Cannnot exec %s", rshpath); - /*FALLTHROUGH*/ - default: - break; - } - - close(Ptc[i][0]); close(Ctp[i][1]); -#endif - -/* - * now attempt to open the tape device - */ - - (void)snprintf(buffer, sizeof(buffer), "O%s\n%d\n", device, oflag); - if (command(i, buffer) == -1 || status(i) == -1) - return -1; - - return i; -} - - -/* - * _rmt_close --- close a remote magtape unit and shut down - */ -static int -_rmt_close(int fildes) -{ - int rc; - - if (command(fildes, "C\n") != -1) { - rc = status(fildes); - - rmtabort(fildes); - return rc; - } - - return -1; -} - - -/* - * _rmt_read --- read a buffer from a remote tape - */ -static ssize_t -_rmt_read(int fildes, void *buf, size_t nbyte) -{ - size_t rc; - int rv; - ssize_t nread; - char *p; - char buffer[BUFMAGIC]; - - _DIAGASSERT(buf != NULL); - - (void)snprintf(buffer, sizeof buffer, "R%zu\n", nbyte); - if (command(fildes, buffer) == -1 || (rv = status(fildes)) == -1) - return -1; - - if (rv > (int)nbyte) - rv = (int)nbyte; - - for (rc = rv, p = buf; rc > 0; rc -= nread, p += nread) { - if ((nread = read(READ(fildes), p, rc)) <= 0) { - rmtabort(fildes); - errno = EIO; - return -1; - } - } - - return rv; -} - - -/* - * _rmt_write --- write a buffer to the remote tape - */ -static ssize_t -_rmt_write(int fildes, const void *buf, size_t nbyte) -{ - char buffer[BUFMAGIC]; - sig_t pstat; - - _DIAGASSERT(buf != NULL); - - (void)snprintf(buffer, sizeof buffer, "W%zu\n", nbyte); - if (command(fildes, buffer) == -1) - return -1; - - pstat = signal(SIGPIPE, SIG_IGN); - if ((size_t)write(WRITE(fildes), buf, nbyte) == nbyte) { - signal(SIGPIPE, pstat); - return status(fildes); - } - - signal(SIGPIPE, pstat); - rmtabort(fildes); - errno = EIO; - return -1; -} - - -/* - * _rmt_lseek --- perform an imitation lseek operation remotely - */ -static off_t -_rmt_lseek(int fildes, off_t offset, int whence) -{ - char buffer[BUFMAGIC]; - - /*LONGLONG*/ - (void)snprintf(buffer, sizeof buffer, "L%lld\n%d\n", (long long)offset, - whence); - if (command(fildes, buffer) == -1) - return -1; - - return status(fildes); -} - - -/* - * _rmt_ioctl --- perform raw tape operations remotely - */ -#ifdef RMTIOCTL -static int -_rmt_ioctl(int fildes, unsigned long op, void *arg) -{ - char c; - int rv; - size_t rc; - ssize_t cnt; - char buffer[BUFMAGIC], *p; - struct mtop *mtop = arg; - - _DIAGASSERT(arg != NULL); - -/* - * MTIOCOP is the easy one. nothing is transfered in binary - */ - - if (op == MTIOCTOP) { - (void)snprintf(buffer, sizeof buffer, "I%d\n%d\n", - mtop->mt_op, mtop->mt_count); - if (command(fildes, buffer) == -1) - return -1; - return status(fildes); - } - -/* - * we can only handle 2 ops, if not the other one, punt - */ - - if (op != MTIOCGET) { - errno = EINVAL; - return -1; - } - -/* - * grab the status and read it directly into the structure - * this assumes that the status buffer is (hopefully) not - * padded and that 2 shorts fit in a long without any word - * alignment problems, ie - the whole struct is contiguous - * NOTE - this is probably NOT a good assumption. - */ - - if (command(fildes, "S") == -1 || (rv = status(fildes)) == -1) - return -1; - - memset(arg, 0, sizeof(struct mtget)); - for (rc = rv, p = arg; rc > 0; rc -= cnt, p += cnt) { - if ((cnt = read(READ(fildes), p, rc)) <= 0) { - rmtabort(fildes); - errno = EIO; - return -1; - } - } - -/* - * now we check for byte position. mt_type is a small integer field - * (normally) so we will check its magnitude. if it is larger than - * 256, we will assume that the bytes are swapped and go through - * and reverse all the bytes - */ - - if (((struct mtget *)(void *)p)->mt_type < 256) - return 0; - - for (cnt = 0; cnt < rv; cnt += 2) { - c = p[cnt]; - p[cnt] = p[cnt + 1]; - p[cnt + 1] = c; - } - - return 0; -} -#endif /* RMTIOCTL */ - - -/* - * Added routines to replace open(), close(), lseek(), ioctl(), etc. - * The preprocessor can be used to remap these the rmtopen(), etc - * thus minimizing source changes: - * - * #ifdef - * # define access rmtaccess - * # define close rmtclose - * # define creat rmtcreat - * # define dup rmtdup - * # define fcntl rmtfcntl - * # define fstat rmtfstat - * # define ioctl rmtioctl - * # define isatty rmtisatty - * # define lseek rmtlseek - * # define lstat rmtlstat - * # define open rmtopen - * # define read rmtread - * # define stat rmtstat - * # define write rmtwrite - * #endif - * - * -- Fred Fish - * - * ADR --- I set up a include file for this - * - */ - -/* - * Note that local vs remote file descriptors are distinquished - * by adding a bias to the remote descriptors. This is a quick - * and dirty trick that may not be portable to some systems. - */ - -#define REM_BIAS 128 - - -/* - * Test pathname to see if it is local or remote. A remote device - * is any string that contains ":/dev/". Returns 1 if remote, - * 0 otherwise. - */ - -static int -remdev(const char *path) -{ - - _DIAGASSERT(path != NULL); - - if ((path = strchr(path, ':')) != NULL) { - if (strncmp(path + 1, "/dev/", 5) == 0) { - return 1; - } - } - return 0; -} - - -/* - * Open a local or remote file. Looks just like open(2) to - * caller. - */ -int -rmtopen(const char *path, int oflag, ...) -{ - mode_t mode; - int fd; - va_list ap; - va_start(ap, oflag); - - mode = va_arg(ap, mode_t); - va_end(ap); - - _DIAGASSERT(path != NULL); - - if (remdev(path)) { - fd = _rmt_open(path, oflag, (int)mode); - - return (fd == -1) ? -1 : (fd + REM_BIAS); - } else { - return open(path, oflag, mode); - } -} - -/* - * Test pathname for specified access. Looks just like access(2) - * to caller. - */ - -int -rmtaccess(const char *path, int amode) -{ - - _DIAGASSERT(path != NULL); - - if (remdev(path)) { - return 0; /* Let /etc/rmt find out */ - } else { - return access(path, amode); - } -} - - -/* - * Isrmt. Let a programmer know he has a remote device. - */ -int -isrmt(int fd) -{ - int unbias = fd - REM_BIAS; - - return (fd >= REM_BIAS) && unbias < MAXUNIT && - (WRITE(unbias) != -1 || READ(unbias) != -1); -} - - -/* - * Read from stream. Looks just like read(2) to caller. - */ -ssize_t -rmtread(int fildes, void *buf, size_t nbyte) -{ - - _DIAGASSERT(buf != NULL); - - if (isrmt(fildes)) { - return _rmt_read(fildes - REM_BIAS, buf, nbyte); - } else { - return read(fildes, buf, nbyte); - } -} - - -/* - * Write to stream. Looks just like write(2) to caller. - */ -ssize_t -rmtwrite(int fildes, const void *buf, size_t nbyte) -{ - - _DIAGASSERT(buf != NULL); - - if (isrmt(fildes)) { - return _rmt_write(fildes - REM_BIAS, buf, nbyte); - } else { - return write(fildes, buf, nbyte); - } -} - -/* - * Perform lseek on file. Looks just like lseek(2) to caller. - */ -off_t -rmtlseek(int fildes, off_t offset, int whence) -{ - - if (isrmt(fildes)) { - return _rmt_lseek(fildes - REM_BIAS, offset, whence); - } else { - return lseek(fildes, offset, whence); - } -} - - -/* - * Close a file. Looks just like close(2) to caller. - */ -int -rmtclose(int fildes) -{ - - if (isrmt(fildes)) { - return _rmt_close(fildes - REM_BIAS); - } else { - return close(fildes); - } -} - - -/* - * Do ioctl on file. Looks just like ioctl(2) to caller. - */ -int -rmtioctl(int fildes, unsigned long request, ...) -{ - void *arg; - va_list ap; - va_start(ap, request); - - arg = va_arg(ap, void *); - va_end(ap); - - /* XXX: arg may be NULL ? */ - - if (isrmt(fildes)) { -#ifdef RMTIOCTL - return _rmt_ioctl(fildes - REM_BIAS, request, arg); -#else - errno = EOPNOTSUPP; - return -1; /* For now (fnf) */ -#endif - } else { - return ioctl(fildes, request, arg); - } -} - - -/* - * Duplicate an open file descriptor. Looks just like dup(2) - * to caller. - */ -int -rmtdup(int fildes) -{ - - if (isrmt(fildes)) { - errno = EOPNOTSUPP; - return -1; /* For now (fnf) */ - } else { - return dup(fildes); - } -} - - -/* - * Get file status. Looks just like fstat(2) to caller. - */ -int -rmtfstat(int fildes, struct stat *buf) -{ - - _DIAGASSERT(buf != NULL); - - if (isrmt(fildes)) { - errno = EOPNOTSUPP; - return -1; /* For now (fnf) */ - } else { - return fstat(fildes, buf); - } -} - - -/* - * Get file status. Looks just like stat(2) to caller. - */ -int -rmtstat(const char *path, struct stat *buf) -{ - - _DIAGASSERT(path != NULL); - _DIAGASSERT(buf != NULL); - - if (remdev(path)) { - errno = EOPNOTSUPP; - return -1; /* For now (fnf) */ - } else { - return stat(path, buf); - } -} - - -/* - * Create a file from scratch. Looks just like creat(2) to the caller. - */ -int -rmtcreat(const char *path, mode_t mode) -{ - - _DIAGASSERT(path != NULL); - - if (remdev(path)) { - return rmtopen(path, O_WRONLY | O_CREAT, mode); - } else { - return open(path, O_CREAT | O_TRUNC | O_WRONLY, mode); - } -} - - -/* - * Rmtfcntl. Do a remote fcntl operation. - */ -int -rmtfcntl(int fd, int cmd, ...) -{ - void *arg; - va_list ap; - va_start(ap, cmd); - - arg = va_arg(ap, void *); - va_end(ap); - - /* XXX: arg may be NULL ? */ - - if (isrmt(fd)) { - errno = EOPNOTSUPP; - return -1; - } else { - return fcntl(fd, cmd, arg); - } -} - - -/* - * Rmtisatty. Do the isatty function. - */ -int -rmtisatty(int fd) -{ - - if (isrmt(fd)) - return 0; - else - return isatty(fd); -} - - -/* - * Get file status, even if symlink. Looks just like lstat(2) to caller. - */ -int -rmtlstat(const char *path, struct stat *buf) -{ - - _DIAGASSERT(path != NULL); - _DIAGASSERT(buf != NULL); - - if (remdev(path)) { - errno = EOPNOTSUPP; - return -1; /* For now (fnf) */ - } else { - return lstat(path, buf); - } -} diff --git a/lib/librmt/rmtops.3 b/lib/librmt/rmtops.3 deleted file mode 100644 index 390d4527f..000000000 --- a/lib/librmt/rmtops.3 +++ /dev/null @@ -1,182 +0,0 @@ -.\" $NetBSD: rmtops.3,v 1.14 2010/03/22 22:00:37 joerg Exp $ -.\" -.Dd October 16, 2001 -.Dt RMTOPS 3 -.Os -.Sh NAME -.Nm rmtops -.Nd access tape drives on remote machines -.Sh LIBRARY -Remote Magnetic Tape Library (librmt, -lrmt) -.Sh SYNOPSIS -.In rmt.h -.In sys/stat.h -.Ft int -.Fn isrmt "int fd" -.Ft int -.Fn rmtaccess "char *file" "int mode" -.Ft int -.Fn rmtclose "int fd" -.Ft int -.Fn rmtcreat "char *file" "int mode" -.Ft int -.Fn rmtdup "int fd" -.Ft int -.Fn rmtfcntl "int fd" "int cmd" "int arg" -.Ft int -.Fn rmtfstat "int fd" "struct stat *buf" -.Ft int -.Fn rmtioctl "int fd" "int request" "char *argp" -.Ft int -.Fn rmtisatty "int fd" -.Ft long -.Fn rmtlseek "int fd" "long offset" "int whence" -.Ft int -.Fn rmtlstat "char *file" "struct stat *buf" -.Ft int -.Fn rmtopen "char *file" "int flags" "int mode" -.Ft int -.Fn rmtread "int fd" "char *buf" "int nbytes" -.Ft int -.Fn rmtstat "char *file" "struct stat *buf" -.Ft int -.Fn rmtwrite "int fd" "char *buf" "int nbytes" -.Sh DESCRIPTION -The -.Nm -library provides a simple means of transparently accessing tape drives -on remote machines via -.Xr rsh 1 -and -.Xr rmt 8 . -These routines are used like their corresponding system calls, but -allow the user to open up a tape drive on a remote system on which he -or she has an account and the appropriate remote permissions. -.Pp -A remote tape drive file name has the form -.Dl [user@]hostname:/dev/??? -where -.Em system -is the remote system, -.Em /dev/??? -is the particular drive on the remote system (raw, blocked, rewinding, -non-rewinding, etc.), and the optional -.Em user -is the login name to be used on the remote system, if different from -the current user's login name. -.\" .Pp -.\" The library source code may be optionally compiled to recognize the -.\" old -.\" .Bx 4.2 , -.\" remote syntax -.\" .sp -.\" hostname[.user]:/dev/??? -.\" .sp -.\" By default, only the first form (introduced in -.\" .Bx 4.3 ) -.\" is recognized. -.Pp -For transparency, the user should include the file -.In rmt.h , -which has the following defines in it: -.Bd -literal -#define access rmtaccess -#define close rmtclose -#define creat rmtcreat -#define dup rmtdup -#define fcntl rmtfcntl -#define fstat rmtfstat -#define ioctl rmtioctl -#define isatty rmtisatty -#define lseek rmtlseek -#define lstat rmtlstat -#define open rmtopen -#define read rmtread -#define stat rmtstat -#define write rmtwrite -.Ed -.Pp -This allows the programmer to use -.Xr open 2 , -.Xr close 2 , -.Xr read 2 , -.Xr write 2 , -etc. in their normal fashion, with the -.Nm -routines taking care of differentiating between local and remote files. -This file should be included -.Em before -including the file -.Pa \*[Lt]sys/stat.h\*[Gt] , -since it redefines the identifier ``stat'' which is used to declare -objects of type -.Em "struct stat" . -.Pp -The routines differentiate between local and remote file descriptors -by adding a bias (currently 128) to the file descriptor of the pipe. -The programmer, if he or she must know if a file is remote, should use -.Fn isrmt . -.Sh ENVIRONMENT -The RCMD_CMD environment variable can be set to the name or pathname -of a program to use, instead of -.Pa /usr/bin/rsh , -and must have the same calling conventions as -.Xr rsh 1 . -.Sh FILES -.Bl -tag -width /usr/lib/librmt.a -compact -.It Pa /usr/lib/librmt.a -remote tape library -.El -.Sh DIAGNOSTICS -Several of these routines will return \-1 and set -.Va errno -to EOPNOTSUPP, if they are given a remote file name or a file descriptor -on an open remote file (e.g., -.Fn rmtdup ) . -.Sh SEE ALSO -.Xr rcp 1 , -.Xr rsh 1 , -.Xr rmt 8 -.Pp -And the appropriate system calls in section 2. -.\" .Sh CONFIGURATION OPTIONS -.\" The library may be compiled to allow the use of -.\" .Bx 4.2 -style -.\" remote file names. This is not recommended. -.\" .Pp -.\" By default, the library opens two pipes to -.\" .Xr rsh 1 . -.\" It may optionally be compiled to use -.\" .Xr rexec 3 , -.\" instead. Doing so requires the use of a -.\" .Em .netrc -.\" file in the user's home directory, or that the application designer be -.\" willing to have -.\" .Xr rexec 3 -.\" prompt the user for a login name and password on the remote host. -.Sh AUTHORS -Jeff Lee wrote the original routines for accessing tape drives via -.Xr rmt 8 . -.Pp -Fred Fish redid them into a general purpose library. -.Pp -Arnold Robbins added the ability to specify a user name on the remote -system, the -.Pa \*[Lt]rmt.h\*[Gt] -include file, this man page, cleaned up the library a little, and made -the appropriate changes for -.Bx 4.3 . -.Pp -Dan Kegel contributed the code to use the -.Xr rexec 3 -library routine. -.Sh BUGS -There is no way to use remote tape drives with -.Xr stdio 3 , -short of recompiling it entirely to use these routines. -.Pp -The -.Xr rmt 8 -protocol is not very capable. -In particular, it relies on TCP/IP sockets for error -free transmission, and does no data validation of its own. diff --git a/lib/libtelnet/Makefile b/lib/libtelnet/Makefile deleted file mode 100644 index fde8b8dc0..000000000 --- a/lib/libtelnet/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# from: @(#)Makefile 8.2 (Berkeley) 12/15/93 -# $NetBSD: Makefile,v 1.36 2012/08/10 12:20:10 joerg Exp $ - -USE_FORT?= yes # network protocol library - -LIBISPRIVATE= yes - -.include - -WARNS?= 5 - -LIB= telnet -SRCS= auth.c encrypt.c genget.c getent.c misc.c - -CPPFLAGS+= -DHAS_CGETENT -CPPFLAGS+= -I${.CURDIR} - -.if ${MKCRYPTO} != "no" -SRCS+= enc_des.c -CPPFLAGS+= -DENCRYPTION -DAUTHENTICATION -CPPFLAGS+= -DDES_ENCRYPTION -.endif - -.if ${USE_KERBEROS} != "no" -SRCS+= kerberos5.c -CPPFLAGS+= -DKRB5 -.endif - -.if ${USE_PAM} != "no" && ${MKCRYPTO} != "no" -SRCS+= sra.c pk.c -CPPFLAGS+= -DSRA -.endif - -.for f in auth enc_des kerberos5 pk -COPTS.${f}.c+= -Wno-pointer-sign -.endfor - -.include diff --git a/lib/libtelnet/auth-proto.h b/lib/libtelnet/auth-proto.h deleted file mode 100644 index 4262553a7..000000000 --- a/lib/libtelnet/auth-proto.h +++ /dev/null @@ -1,103 +0,0 @@ -/* $NetBSD: auth-proto.h,v 1.15 2006/03/20 21:23:47 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)auth-proto.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifndef _LIBTELNET_AUTH_PROTO_H_ -#define _LIBTELNET_AUTH_PROTO_H_ -#include - -#ifdef AUTHENTICATION -Authenticator *findauthenticator(int, int); - -void auth_init(const char *, int); -int auth_cmd(int, char **); -void auth_request(void); -void auth_send(unsigned char *, int); -void auth_send_retry(void); -void auth_is(unsigned char *, int); -void auth_reply(unsigned char *, int); -void auth_disable_name(char *); -void auth_gen_printsub(unsigned char *, int, unsigned char *, int); - -int getauthmask(char *, int *); -int auth_enable(char *); -int auth_disable(char *); -int auth_onoff(char *, int); -int auth_togdebug(int); -int auth_status(char *); -void auth_name(unsigned char *, int); -int auth_sendname(unsigned char *, int); -void auth_finished(Authenticator *, int); -int auth_wait(char *, size_t); -void auth_debug(int); -void auth_printsub(unsigned char *, int, unsigned char *, int); - -#ifdef KRB5 -int kerberos5_init(Authenticator *, int); -int kerberos5_send(Authenticator *); -void kerberos5_is(Authenticator *, unsigned char *, int); -void kerberos5_reply(Authenticator *, unsigned char *, int); -int kerberos5_status(Authenticator *, char *, size_t, int); -void kerberos5_printsub(unsigned char *, int, unsigned char *, int); -#endif - -#ifdef SRA -int sra_init(Authenticator *, int); -int sra_send(Authenticator *); -void sra_is(Authenticator *, unsigned char *, int); -void sra_reply(Authenticator *, unsigned char *, int); -int sra_status(Authenticator *, char *, size_t, int); -void sra_printsub(unsigned char *, int, unsigned char *, int); -#endif - -#endif /* AUTHENTICATION */ -#endif /* _LIBTELNET_AUTH_PROTO_H_ */ diff --git a/lib/libtelnet/auth.c b/lib/libtelnet/auth.c deleted file mode 100644 index 3db63333f..000000000 --- a/lib/libtelnet/auth.c +++ /dev/null @@ -1,617 +0,0 @@ -/* $NetBSD: auth.c,v 1.21 2012/03/21 05:33:27 matt Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95" -#else -__RCSID("$NetBSD: auth.c,v 1.21 2012/03/21 05:33:27 matt Exp $"); -#endif -#endif /* not lint */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - - -#ifdef AUTHENTICATION -#include -#include -#include -#define AUTH_NAMES -#include -#include -#include -#ifdef NO_STRING_H -#include -#else -#include -#endif - -#include "encrypt.h" -#include "auth.h" -#include "misc-proto.h" -#include "auth-proto.h" - -#define typemask(x) (1<<((x)-1)) - -#ifdef RSA_ENCPWD -extern rsaencpwd_init(); -extern rsaencpwd_send(); -extern rsaencpwd_is(); -extern rsaencpwd_reply(); -extern rsaencpwd_status(); -extern rsaencpwd_printsub(); -#endif - -int auth_debug_mode = 0; -static const char *Name = "Noname"; -static int Server = 0; -static Authenticator *authenticated = 0; -static int authenticating = 0; -static int validuser = 0; -static unsigned char _auth_send_data[256]; -static unsigned char *auth_send_data; -static int auth_send_cnt = 0; - -static void auth_intr(int); - -/* - * Authentication types supported. Plese note that these are stored - * in priority order, i.e. try the first one first. - */ -Authenticator authenticators[] = { -#ifdef SPX - { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, - spx_init, - spx_send, - spx_is, - spx_reply, - spx_status, - spx_printsub }, - { AUTHTYPE_SPX, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, - spx_init, - spx_send, - spx_is, - spx_reply, - spx_status, - spx_printsub }, -#endif -#ifdef KRB5 -# ifdef ENCRYPTION - { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_MUTUAL, - kerberos5_init, - kerberos5_send, - kerberos5_is, - kerberos5_reply, - kerberos5_status, - kerberos5_printsub }, -# endif /* ENCRYPTION */ - { AUTHTYPE_KERBEROS_V5, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, - kerberos5_init, - kerberos5_send, - kerberos5_is, - kerberos5_reply, - kerberos5_status, - kerberos5_printsub }, -#endif -#ifdef RSA_ENCPWD - { AUTHTYPE_RSA_ENCPWD, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, - rsaencpwd_init, - rsaencpwd_send, - rsaencpwd_is, - rsaencpwd_reply, - rsaencpwd_status, - rsaencpwd_printsub }, -#endif -#ifdef SRA - { AUTHTYPE_SRA, AUTH_WHO_CLIENT|AUTH_HOW_ONE_WAY, - sra_init, - sra_send, - sra_is, - sra_reply, - sra_status, - sra_printsub }, - -#endif - { 0, 0, 0, 0, 0, 0, 0, 0 }, -}; - -static Authenticator NoAuth = { .type = 0 }; - -static int i_support = 0; -static int i_wont_support = 0; - -Authenticator * -findauthenticator(int type, int way) -{ - Authenticator *ap = authenticators; - - while (ap->type && (ap->type != type || ap->way != way)) - ++ap; - return(ap->type ? ap : 0); -} - -void -auth_init(const char *name, int server) -{ - Authenticator *ap = authenticators; - - Server = server; - Name = name; - - i_support = 0; - authenticated = 0; - authenticating = 0; - while (ap->type) { - if (!ap->init || (*ap->init)(ap, server)) { - i_support |= typemask(ap->type); - if (auth_debug_mode) - printf(">>>%s: I support auth type %d %d\r\n", - Name, - ap->type, ap->way); - } - else if (auth_debug_mode) - printf(">>>%s: Init failed: auth type %d %d\r\n", - Name, ap->type, ap->way); - ++ap; - } -} - -void -auth_disable_name(char *name) -{ - int x; - for (x = 0; x < AUTHTYPE_CNT; ++x) { - if (AUTHTYPE_NAME(x) && !strcasecmp(name, AUTHTYPE_NAME(x))) { - i_wont_support |= typemask(x); - break; - } - } -} - -int -getauthmask(char *type, int *maskp) -{ - register int x; - - if (AUTHTYPE_NAME(0) && !strcasecmp(type, AUTHTYPE_NAME(0))) { - *maskp = -1; - return(1); - } - - for (x = 1; x < AUTHTYPE_CNT; ++x) { - if (AUTHTYPE_NAME(x) && !strcasecmp(type, AUTHTYPE_NAME(x))) { - *maskp = typemask(x); - return(1); - } - } - return(0); -} - -int -auth_enable(char *type) -{ - return(auth_onoff(type, 1)); -} - -int -auth_disable(char *type) -{ - return(auth_onoff(type, 0)); -} - -int -auth_onoff(char *type, int on) -{ - int i, mask = -1; - Authenticator *ap; - - if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) { - printf("auth %s 'type'\n", on ? "enable" : "disable"); - printf("Where 'type' is one of:\n"); - printf("\t%s\n", AUTHTYPE_NAME(0)); - mask = 0; - for (ap = authenticators; ap->type; ap++) { - if ((mask & (i = typemask(ap->type))) != 0) - continue; - mask |= i; - printf("\t%s\n", AUTHTYPE_NAME(ap->type)); - } - return(0); - } - - if (!getauthmask(type, &mask)) { - printf("%s: invalid authentication type\n", type); - return(0); - } - if (on) - i_wont_support &= ~mask; - else - i_wont_support |= mask; - return(1); -} - -int -auth_togdebug(int on) -{ - if (on < 0) - auth_debug_mode ^= 1; - else - auth_debug_mode = on; - printf("auth debugging %s\n", auth_debug_mode ? "enabled" : "disabled"); - return(1); -} - -int -auth_status(char *s) -{ - Authenticator *ap; - int i, mask; - - if (i_wont_support == -1) - printf("Authentication disabled\n"); - else - printf("Authentication enabled\n"); - - mask = 0; - for (ap = authenticators; ap->type; ap++) { - if ((mask & (i = typemask(ap->type))) != 0) - continue; - mask |= i; - printf("%s: %s\n", AUTHTYPE_NAME(ap->type), - (i_wont_support & typemask(ap->type)) ? - "disabled" : "enabled"); - } - return(1); -} - -/* - * This routine is called by the server to start authentication - * negotiation. - */ -void -auth_request(void) -{ - static unsigned char str_request[64] = { IAC, SB, - TELOPT_AUTHENTICATION, - TELQUAL_SEND, }; - Authenticator *ap = authenticators; - unsigned char *e = str_request + 4; - - if (!authenticating) { - authenticating = 1; - while (ap->type) { - if (i_support & ~i_wont_support & typemask(ap->type)) { - if (auth_debug_mode) { - printf(">>>%s: Sending type %d %d\r\n", - Name, ap->type, ap->way); - } - *e++ = ap->type; - *e++ = ap->way; - } - ++ap; - } - *e++ = IAC; - *e++ = SE; - telnet_net_write(str_request, e - str_request); - printsub('>', &str_request[2], e - str_request - 2); - } -} - -/* - * This is called when an AUTH SEND is received. - * It should never arrive on the server side (as only the server can - * send an AUTH SEND). - * You should probably respond to it if you can... - * - * If you want to respond to the types out of order (i.e. even - * if he sends LOGIN KERBEROS and you support both, you respond - * with KERBEROS instead of LOGIN (which is against what the - * protocol says)) you will have to hack this code... - */ -void -auth_send(unsigned char *data, int cnt) -{ - Authenticator *ap; - static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, - TELQUAL_IS, AUTHTYPE_NULL, 0, - IAC, SE }; - if (Server) { - if (auth_debug_mode) { - printf(">>>%s: auth_send called!\r\n", Name); - } - return; - } - - if (auth_debug_mode) { - printf(">>>%s: auth_send got:", Name); - printd(data, cnt); printf("\r\n"); - } - - /* - * Save the data, if it is new, so that we can continue looking - * at it if the authorization we try doesn't work - */ - if (data < _auth_send_data || - data > _auth_send_data + sizeof(_auth_send_data)) { - auth_send_cnt = (size_t)cnt > sizeof(_auth_send_data) - ? sizeof(_auth_send_data) - : (size_t)cnt; - memmove(_auth_send_data, data, auth_send_cnt); - auth_send_data = _auth_send_data; - } else { - /* - * This is probably a no-op, but we just make sure - */ - auth_send_data = data; - auth_send_cnt = cnt; - } - while ((auth_send_cnt -= 2) >= 0) { - if (auth_debug_mode) - printf(">>>%s: He supports %d\r\n", - Name, *auth_send_data); - if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { - ap = findauthenticator(auth_send_data[0], - auth_send_data[1]); - if (ap && ap->send) { - if (auth_debug_mode) - printf(">>>%s: Trying %d %d\r\n", - Name, auth_send_data[0], - auth_send_data[1]); - if ((*ap->send)(ap)) { - /* - * Okay, we found one we like - * and did it. - * we can go home now. - */ - if (auth_debug_mode) - printf(">>>%s: Using type %d\r\n", - Name, *auth_send_data); - auth_send_data += 2; - return; - } - } - /* else - * just continue on and look for the - * next one if we didn't do anything. - */ - } - auth_send_data += 2; - } - telnet_net_write(str_none, sizeof(str_none)); - printsub('>', &str_none[2], sizeof(str_none) - 2); - if (auth_debug_mode) - printf(">>>%s: Sent failure message\r\n", Name); - auth_finished(0, AUTH_REJECT); -#ifdef KANNAN - /* - * We requested strong authentication, however no mechanisms worked. - * Therefore, exit on client end. - */ - printf("Unable to securely authenticate user ... exit\n"); - exit(0); -#endif /* KANNAN */ -} - -void -auth_send_retry(void) -{ - /* - * if auth_send_cnt <= 0 then auth_send will end up rejecting - * the authentication and informing the other side of this. - */ - auth_send(auth_send_data, auth_send_cnt); -} - -void -auth_is(unsigned char *data, int cnt) -{ - Authenticator *ap; - - if (cnt < 2) - return; - - if (data[0] == AUTHTYPE_NULL) { - auth_finished(0, AUTH_REJECT); - return; - } - - if ((ap = findauthenticator(data[0], data[1])) != NULL) { - if (ap->is) - (*ap->is)(ap, data+2, cnt-2); - } else if (auth_debug_mode) - printf(">>>%s: Invalid authentication in IS: %d\r\n", - Name, *data); -} - -void -auth_reply(unsigned char *data, int cnt) -{ - Authenticator *ap; - - if (cnt < 2) - return; - - if ((ap = findauthenticator(data[0], data[1])) != NULL) { - if (ap->reply) - (*ap->reply)(ap, data+2, cnt-2); - } else if (auth_debug_mode) - printf(">>>%s: Invalid authentication in SEND: %d\r\n", - Name, *data); -} - -void -auth_name(unsigned char *data, int cnt) -{ - unsigned char savename[256]; - - if (cnt < 1) { - if (auth_debug_mode) - printf(">>>%s: Empty name in NAME\r\n", Name); - return; - } - if ((size_t)cnt > sizeof(savename) - 1) { - if (auth_debug_mode) - printf(">>>%s: Name in NAME (%d) exceeds %ld length\r\n", - Name, cnt, (long)sizeof(savename)-1); - return; - } - memmove((void *)savename, (void *)data, cnt); - savename[cnt] = '\0'; /* Null terminate */ - if (auth_debug_mode) - printf(">>>%s: Got NAME [%s]\r\n", Name, savename); - auth_encrypt_user(savename); -} - -int -auth_sendname(unsigned char *cp, int len) -{ - static unsigned char str_request[256+6] - = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; - register unsigned char *e = str_request + 4; - register unsigned char *ee = &str_request[sizeof(str_request)-2]; - - while (--len >= 0) { - if ((*e++ = *cp++) == IAC) - *e++ = IAC; - if (e >= ee) - return(0); - } - *e++ = IAC; - *e++ = SE; - telnet_net_write(str_request, e - str_request); - printsub('>', &str_request[2], e - &str_request[2]); - return(1); -} - -void -auth_finished(Authenticator *ap, int result) -{ - if (!(authenticated = ap)) - authenticated = &NoAuth; - validuser = result; -} - - /* ARGSUSED */ -static void -auth_intr(int sig) -{ - auth_finished(0, AUTH_REJECT); -} - -int -auth_wait(char *name, size_t l) -{ - if (auth_debug_mode) - printf(">>>%s: in auth_wait.\r\n", Name); - - if (Server && !authenticating) - return(0); - - (void) signal(SIGALRM, auth_intr); - alarm(30); - while (!authenticated) - if (telnet_spin()) - break; - alarm(0); - (void) signal(SIGALRM, SIG_DFL); - - /* - * Now check to see if the user is valid or not - */ - if (!authenticated || authenticated == &NoAuth) - return(AUTH_REJECT); - - if (validuser == AUTH_VALID) - validuser = AUTH_USER; - - if (authenticated->status) - validuser = (*authenticated->status)(authenticated, - name, l, validuser); - return(validuser); -} - -void -auth_debug(int mode) -{ - auth_debug_mode = mode; -} - -void -auth_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) -{ - Authenticator *ap; - - if ((ap = findauthenticator(data[1], data[2])) && ap->printsub) - (*ap->printsub)(data, cnt, buf, buflen); - else - auth_gen_printsub(data, cnt, buf, buflen); -} - -void -auth_gen_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) -{ - register unsigned char *cp; - unsigned char tbuf[16]; - - cnt -= 3; - data += 3; - buf[buflen-1] = '\0'; - buf[buflen-2] = '*'; - buflen -= 2; - for (; cnt > 0; cnt--, data++) { - snprintf((char *)tbuf, sizeof(tbuf), " %d", *data); - for (cp = tbuf; *cp && buflen > 0; --buflen) - *buf++ = *cp++; - if (buflen <= 0) - return; - } - *buf = '\0'; -} -#endif diff --git a/lib/libtelnet/auth.h b/lib/libtelnet/auth.h deleted file mode 100644 index aab6f9373..000000000 --- a/lib/libtelnet/auth.h +++ /dev/null @@ -1,80 +0,0 @@ -/* $NetBSD: auth.h,v 1.11 2005/02/06 05:53:07 perry Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)auth.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifndef __AUTH__ -#define __AUTH__ - -#define AUTH_REJECT 0 /* Rejected */ -#define AUTH_UNKNOWN 1 /* We don't know who he is, but he's okay */ -#define AUTH_OTHER 2 /* We know him, but not his name */ -#define AUTH_USER 3 /* We know he name */ -#define AUTH_VALID 4 /* We know him, and he needs no password */ - -typedef struct XauthP { - int type; - int way; - int (*init)(struct XauthP *, int); - int (*send)(struct XauthP *); - void (*is)(struct XauthP *, unsigned char *, int); - void (*reply)(struct XauthP *, unsigned char *, int); - int (*status)(struct XauthP *, char *, size_t, int); - void (*printsub)(unsigned char *, int, unsigned char *, int); -} Authenticator; - -#include "auth-proto.h" - -#define OPTS_FORWARD_CREDS 0x00000002 -#define OPTS_FORWARDABLE_CREDS 0x00000001 - -extern int auth_debug_mode; -#endif diff --git a/lib/libtelnet/enc-proto.h b/lib/libtelnet/enc-proto.h deleted file mode 100644 index 5e62de060..000000000 --- a/lib/libtelnet/enc-proto.h +++ /dev/null @@ -1,140 +0,0 @@ -/* $NetBSD: enc-proto.h,v 1.9 2012/01/09 15:25:33 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)enc-proto.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifdef ENCRYPTION -#include - -Encryptions *findencryption(int); -Encryptions *finddecryption(int); -void encrypt_init(const char *, int); -void encrypt_list_types(void); -int EncryptEnable(char *, char *); -int EncryptDisable(char *, char *); -int EncryptType(char *, char *); -int EncryptStart(char *); -int EncryptStartInput(void); -int EncryptStartOutput(void); -int EncryptStop(char *); -int EncryptStopInput(void); -int EncryptStopOutput(void); -int EncryptStatus(void); -void encrypt_send_support(void); -int EncryptDebug(int); -int EncryptVerbose(int); -int EncryptAutoEnc(int); -int EncryptAutoDec(int); -void encrypt_support(unsigned char *, int); -void encrypt_is(unsigned char *, int); -void encrypt_reply(unsigned char *, int); -void encrypt_start(unsigned char *, int); -void encrypt_session_key(Session_Key *, int); -void encrypt_end(void); -void encrypt_request_end(void); -void encrypt_request_start(unsigned char *, int); -void encrypt_enc_keyid(unsigned char *, int); -void encrypt_dec_keyid(unsigned char *, int); -struct key_info; -void encrypt_keyid(struct key_info *, unsigned char *, int); -void encrypt_send_keyid(int, const unsigned char *, int, int); -void encrypt_auto(int); -void decrypt_auto(int); -void encrypt_start_output(int); -void encrypt_send_end(void); -void encrypt_send_request_start(void); -void encrypt_send_request_end(void); -void encrypt_wait(void); -void encrypt_debug(int); -void encrypt_gen_printsub(unsigned char *, int, unsigned char *, int ); -void encrypt_printsub(unsigned char *, int, unsigned char *, int ); - -#ifdef TELENTD -void encrypt_wait(void); -#else -void printsub(int, unsigned char *, int); -int encrypt_cmd(int, char **); -void encrypt_display(void); -#endif - -void krbdes_encrypt(unsigned char *, int); -int krbdes_decrypt(int); -int krbdes_is(unsigned char *, int); -int krbdes_reply(unsigned char *, int); -void krbdes_init(int); -int krbdes_start(int, int); -void krbdes_session(Session_Key *, int); -void krbdes_printsub(unsigned char *, int, unsigned char *, int); - -void cfb64_encrypt(unsigned char *, int); -int cfb64_decrypt(int); -void cfb64_init(int); -int cfb64_start(int, int); -int cfb64_is(unsigned char *, int); -int cfb64_reply(unsigned char *, int); -void cfb64_session(Session_Key *, int); -int cfb64_keyid(int, unsigned char *, int *); -void cfb64_printsub(unsigned char *, int, unsigned char *, int); - -void ofb64_encrypt(unsigned char *, int); -int ofb64_decrypt(int); -void ofb64_init(int); -int ofb64_start(int, int); -int ofb64_is(unsigned char *, int); -int ofb64_reply(unsigned char *, int); -void ofb64_session(Session_Key *, int); -int ofb64_keyid(int, unsigned char *, int *); -void ofb64_printsub(unsigned char *, int, unsigned char *, int); - -void fb64_printsub(const unsigned char *, int, unsigned char *, int, - const unsigned char *); - -#endif /* ENCRYPTION */ diff --git a/lib/libtelnet/enc_des.c b/lib/libtelnet/enc_des.c deleted file mode 100644 index e1cde4ddf..000000000 --- a/lib/libtelnet/enc_des.c +++ /dev/null @@ -1,665 +0,0 @@ -/* $NetBSD: enc_des.c,v 1.16 2012/03/21 05:33:27 matt Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)enc_des.c 8.3 (Berkeley) 5/30/95"; */ -#else -__RCSID("$NetBSD: enc_des.c,v 1.16 2012/03/21 05:33:27 matt Exp $"); -#endif -#endif /* not lint */ - -#ifdef ENCRYPTION -# ifdef AUTHENTICATION -# ifdef DES_ENCRYPTION -#include -#include -#include -#include - -#include -#include "encrypt.h" -#include "key-proto.h" -#include "misc-proto.h" - -#define CFB 0 -#define OFB 1 - -#define NO_SEND_IV 1 -#define NO_RECV_IV 2 -#define NO_KEYID 4 -#define IN_PROGRESS (NO_SEND_IV|NO_RECV_IV|NO_KEYID) -#define SUCCESS 0 -#define FAILED -1 - - -struct fb { - Block krbdes_key; - Schedule krbdes_sched; - Block temp_feed; - unsigned char fb_feed[64]; - int need_start; - int state[2]; - int keyid[2]; - int once; - struct stinfo { - Block str_output; - Block str_feed; - Block str_iv; - Block str_ikey; - Schedule str_sched; - int str_index; - int str_flagshift; - } streams[2]; -}; - -static struct fb fb[2]; - -struct keyidlist { - const char *keyid; - int keyidlen; - char *key; - int keylen; - int flags; -} keyidlist [] = { - { "\0", 1, 0, 0, 0 }, /* default key of zero */ - { 0, 0, 0, 0, 0 } -}; - -#define KEYFLAG_MASK 03 - -#define KEYFLAG_NOINIT 00 -#define KEYFLAG_INIT 01 -#define KEYFLAG_OK 02 -#define KEYFLAG_BAD 03 - -#define KEYFLAG_SHIFT 2 - -#define SHIFT_VAL(a,b) (KEYFLAG_SHIFT*((a)+((b)*2))) - -#define FB64_IV 1 -#define FB64_IV_OK 2 -#define FB64_IV_BAD 3 - - -void fb64_stream_iv(Block, struct stinfo *); -void fb64_init(struct fb *); -static int fb64_start(struct fb *, int, int); -int fb64_is(unsigned char *, int, struct fb *); -int fb64_reply(unsigned char *, int, struct fb *); -static void fb64_session(Session_Key *, int, struct fb *); -void fb64_stream_key(Block *, struct stinfo *); -int fb64_keyid(int, unsigned char *, int *, struct fb *); - -void -cfb64_init(int server) -{ - fb64_init(&fb[CFB]); - fb[CFB].fb_feed[4] = ENCTYPE_DES_CFB64; - fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, CFB); - fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, CFB); -} - -void -ofb64_init(int server) -{ - fb64_init(&fb[OFB]); - fb[OFB].fb_feed[4] = ENCTYPE_DES_OFB64; - fb[CFB].streams[0].str_flagshift = SHIFT_VAL(0, OFB); - fb[CFB].streams[1].str_flagshift = SHIFT_VAL(1, OFB); -} - -void -fb64_init(register struct fb *fbp) -{ - memset((void *)fbp, 0, sizeof(*fbp)); - fbp->state[0] = fbp->state[1] = FAILED; - fbp->fb_feed[0] = IAC; - fbp->fb_feed[1] = SB; - fbp->fb_feed[2] = TELOPT_ENCRYPT; - fbp->fb_feed[3] = ENCRYPT_IS; -} - -/* - * Returns: - * -1: some error. Negotiation is done, encryption not ready. - * 0: Successful, initial negotiation all done. - * 1: successful, negotiation not done yet. - * 2: Not yet. Other things (like getting the key from - * Kerberos) have to happen before we can continue. - */ -int -cfb64_start(int dir, int server) -{ - return(fb64_start(&fb[CFB], dir, server)); -} - -int -ofb64_start(int dir, int server) -{ - return(fb64_start(&fb[OFB], dir, server)); -} - -static int -fb64_start(struct fb *fbp, int dir, int server) -{ - size_t x; - unsigned char *p; - register int state; - - switch (dir) { - case DIR_DECRYPT: - /* - * This is simply a request to have the other side - * start output (our input). He will negotiate an - * IV so we need not look for it. - */ - state = fbp->state[dir-1]; - if (state == FAILED) - state = IN_PROGRESS; - break; - - case DIR_ENCRYPT: - state = fbp->state[dir-1]; - if (state == FAILED) - state = IN_PROGRESS; - else if ((state & NO_SEND_IV) == 0) - break; - - if (!VALIDKEY(fbp->krbdes_key)) { - fbp->need_start = 1; - break; - } - state &= ~NO_SEND_IV; - state |= NO_RECV_IV; - if (encrypt_debug_mode) - printf("Creating new feed\r\n"); - /* - * Create a random feed and send it over. - */ - des_new_random_key(&fbp->temp_feed); - des_ecb_encrypt(&fbp->temp_feed, &fbp->temp_feed, - fbp->krbdes_sched, 1); - p = fbp->fb_feed + 3; - *p++ = ENCRYPT_IS; - p++; - *p++ = FB64_IV; - for (x = 0; x < sizeof(Block); ++x) { - if ((*p++ = fbp->temp_feed[x]) == IAC) - *p++ = IAC; - } - *p++ = IAC; - *p++ = SE; - printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); - telnet_net_write(fbp->fb_feed, p - fbp->fb_feed); - break; - default: - return(FAILED); - } - return(fbp->state[dir-1] = state); -} - -/* - * Returns: - * -1: some error. Negotiation is done, encryption not ready. - * 0: Successful, initial negotiation all done. - * 1: successful, negotiation not done yet. - */ -int -cfb64_is(unsigned char *data, int cnt) -{ - return(fb64_is(data, cnt, &fb[CFB])); -} -int -ofb64_is(unsigned char *data, int cnt) -{ - return(fb64_is(data, cnt, &fb[OFB])); -} - -int -fb64_is(unsigned char *data, int cnt, struct fb *fbp) -{ - unsigned char *p; - register int state = fbp->state[DIR_DECRYPT-1]; - - if (cnt-- < 1) - goto failure; - - switch (*data++) { - case FB64_IV: - if (cnt != sizeof(Block)) { - if (encrypt_debug_mode) - printf("CFB64: initial vector failed on size\r\n"); - state = FAILED; - goto failure; - } - - if (encrypt_debug_mode) - printf("CFB64: initial vector received\r\n"); - - if (encrypt_debug_mode) - printf("Initializing Decrypt stream\r\n"); - - fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]); - - p = fbp->fb_feed + 3; - *p++ = ENCRYPT_REPLY; - p++; - *p++ = FB64_IV_OK; - *p++ = IAC; - *p++ = SE; - printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); - telnet_net_write(fbp->fb_feed, p - fbp->fb_feed); - - state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS; - break; - - default: - if (encrypt_debug_mode) { - printf("Unknown option type: %d\r\n", *(data-1)); - printd(data, cnt); - printf("\r\n"); - } - /* FALL THROUGH */ - failure: - /* - * We failed. Send an FB64_IV_BAD option - * to the other side so it will know that - * things failed. - */ - p = fbp->fb_feed + 3; - *p++ = ENCRYPT_REPLY; - p++; - *p++ = FB64_IV_BAD; - *p++ = IAC; - *p++ = SE; - printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); - telnet_net_write(fbp->fb_feed, p - fbp->fb_feed); - - break; - } - return(fbp->state[DIR_DECRYPT-1] = state); -} - -/* - * Returns: - * -1: some error. Negotiation is done, encryption not ready. - * 0: Successful, initial negotiation all done. - * 1: successful, negotiation not done yet. - */ -int -cfb64_reply(unsigned char *data, int cnt) -{ - return(fb64_reply(data, cnt, &fb[CFB])); -} -int -ofb64_reply(unsigned char *data, int cnt) -{ - return(fb64_reply(data, cnt, &fb[OFB])); -} - -int -fb64_reply(unsigned char *data, int cnt, struct fb *fbp) -{ - register int state = fbp->state[DIR_ENCRYPT-1]; - - if (cnt-- < 1) - goto failure; - - switch (*data++) { - case FB64_IV_OK: - fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); - if (state == FAILED) - state = IN_PROGRESS; - state &= ~NO_RECV_IV; - encrypt_send_keyid(DIR_ENCRYPT, (const unsigned char *)"\0", 1, 1); - break; - - case FB64_IV_BAD: - memset(fbp->temp_feed, 0, sizeof(Block)); - fb64_stream_iv(fbp->temp_feed, &fbp->streams[DIR_ENCRYPT-1]); - state = FAILED; - break; - - default: - if (encrypt_debug_mode) { - printf("Unknown option type: %d\r\n", data[-1]); - printd(data, cnt); - printf("\r\n"); - } - /* FALL THROUGH */ - failure: - state = FAILED; - break; - } - return(fbp->state[DIR_ENCRYPT-1] = state); -} - -void -cfb64_session(Session_Key *key, int server) -{ - fb64_session(key, server, &fb[CFB]); -} - -void -ofb64_session( Session_Key *key, int server) -{ - fb64_session(key, server, &fb[OFB]); -} - -static void -fb64_session(Session_Key *key, int server, struct fb *fbp) -{ - - if (!key || key->type != SK_DES) { - if (encrypt_debug_mode) - printf("Can't set krbdes's session key (%d != %d)\r\n", - key ? key->type : -1, SK_DES); - return; - } - memmove((void *)fbp->krbdes_key, (void *)key->data, sizeof(Block)); - - fb64_stream_key(&fbp->krbdes_key, &fbp->streams[DIR_ENCRYPT-1]); - fb64_stream_key(&fbp->krbdes_key, &fbp->streams[DIR_DECRYPT-1]); - - if (fbp->once == 0) { - des_init_random_number_generator(&fbp->krbdes_key); - fbp->once = 1; - } - des_key_sched(&fbp->krbdes_key, fbp->krbdes_sched); - /* - * Now look to see if krbdes_start() was waiting for the key to - * show up. If so, go ahead an call it now that we have the key. - */ - if (fbp->need_start) { - fbp->need_start = 0; - fb64_start(fbp, DIR_ENCRYPT, server); - } -} - -/* - * We only accept a keyid of 0. If we get a keyid of - * 0, then mark the state as SUCCESS. - */ -int -cfb64_keyid(int dir, unsigned char *kp, int *lenp) -{ - return(fb64_keyid(dir, kp, lenp, &fb[CFB])); -} - - int -ofb64_keyid(int dir, unsigned char *kp, int *lenp) -{ - return(fb64_keyid(dir, kp, lenp, &fb[OFB])); -} - -int -fb64_keyid(int dir, unsigned char *kp, int *lenp, struct fb *fbp) -{ - register int state = fbp->state[dir-1]; - - if (*lenp != 1 || (*kp != '\0')) { - *lenp = 0; - return(state); - } - - if (state == FAILED) - state = IN_PROGRESS; - - state &= ~NO_KEYID; - - return(fbp->state[dir-1] = state); -} - -void -fb64_printsub(const unsigned char *data, int cnt, unsigned char *buf, - int buflen, const unsigned char *type) -{ - char lbuf[32]; - register int i; - char *cp; - - buf[buflen-1] = '\0'; /* make sure it's NULL terminated */ - buflen -= 1; - - switch(data[2]) { - case FB64_IV: - snprintf(lbuf, sizeof(lbuf), "%s_IV", type); - cp = lbuf; - goto common; - - case FB64_IV_OK: - snprintf(lbuf, sizeof(lbuf), "%s_IV_OK", type); - cp = lbuf; - goto common; - - case FB64_IV_BAD: - snprintf(lbuf, sizeof(lbuf), "%s_IV_BAD", type); - cp = lbuf; - goto common; - - default: - snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[2]); - cp = lbuf; - common: - for (; (buflen > 0) && (*buf = *cp++); buf++) - buflen--; - for (i = 3; i < cnt; i++) { - snprintf(lbuf, sizeof(lbuf), " %d", data[i]); - for (cp = lbuf; (buflen > 0) && (*buf = *cp++); buf++) - buflen--; - } - break; - } -} - -void -cfb64_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) -{ - fb64_printsub(data, cnt, buf, buflen, "CFB64"); -} - - void -ofb64_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) -{ - fb64_printsub(data, cnt, buf, buflen, "OFB64"); -} - -void -fb64_stream_iv(Block seed, struct stinfo *stp) -{ - - memmove((void *)stp->str_iv, (void *)seed, sizeof(Block)); - memmove((void *)stp->str_output, (void *)seed, sizeof(Block)); - - des_key_sched(&stp->str_ikey, stp->str_sched); - - stp->str_index = sizeof(Block); -} - -void -fb64_stream_key(Block *key, struct stinfo *stp) -{ - memmove((void *)stp->str_ikey, (void *)key, sizeof(Block)); - des_key_sched(key, stp->str_sched); - - memmove((void *)stp->str_output, (void *)stp->str_iv, sizeof(Block)); - - stp->str_index = sizeof(Block); -} - -/* - * DES 64 bit Cipher Feedback - * - * key --->+-----+ - * +->| DES |--+ - * | +-----+ | - * | v - * INPUT --(--------->(+)+---> DATA - * | | - * +-------------+ - * - * - * Given: - * iV: Initial vector, 64 bits (8 bytes) long. - * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). - * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. - * - * V0 = DES(iV, key) - * On = Dn ^ Vn - * V(n+1) = DES(On, key) - */ - -void -cfb64_encrypt(unsigned char *s, int c) -{ - register struct stinfo *stp = &fb[CFB].streams[DIR_ENCRYPT-1]; - register int idx; - - idx = stp->str_index; - while (c-- > 0) { - if (idx == sizeof(Block)) { - Block b; - des_ecb_encrypt(&stp->str_output, &b, stp->str_sched, 1); - memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); - idx = 0; - } - - /* On encryption, we store (feed ^ data) which is cypher */ - *s = stp->str_output[idx] = (stp->str_feed[idx] ^ *s); - s++; - idx++; - } - stp->str_index = idx; -} - -int -cfb64_decrypt(int data) -{ - register struct stinfo *stp = &fb[CFB].streams[DIR_DECRYPT-1]; - int idx; - - if (data == -1) { - /* - * Back up one byte. It is assumed that we will - * never back up more than one byte. If we do, this - * may or may not work. - */ - if (stp->str_index) - --stp->str_index; - return(0); - } - - idx = stp->str_index++; - if (idx == sizeof(Block)) { - Block b; - des_ecb_encrypt(&stp->str_output, &b, stp->str_sched, 1); - memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); - stp->str_index = 1; /* Next time will be 1 */ - idx = 0; /* But now use 0 */ - } - - /* On decryption we store (data) which is cypher. */ - stp->str_output[idx] = data; - return(data ^ stp->str_feed[idx]); -} - -/* - * DES 64 bit Output Feedback - * - * key --->+-----+ - * +->| DES |--+ - * | +-----+ | - * +-----------+ - * v - * INPUT -------->(+) ----> DATA - * - * Given: - * iV: Initial vector, 64 bits (8 bytes) long. - * Dn: the nth chunk of 64 bits (8 bytes) of data to encrypt (decrypt). - * On: the nth chunk of 64 bits (8 bytes) of encrypted (decrypted) output. - * - * V0 = DES(iV, key) - * V(n+1) = DES(Vn, key) - * On = Dn ^ Vn - */ -void -ofb64_encrypt(unsigned char *s, int c) -{ - register struct stinfo *stp = &fb[OFB].streams[DIR_ENCRYPT-1]; - register int idx; - - idx = stp->str_index; - while (c-- > 0) { - if (idx == sizeof(Block)) { - Block b; - des_ecb_encrypt(&stp->str_feed, &b, stp->str_sched, 1); - memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); - idx = 0; - } - *s++ ^= stp->str_feed[idx]; - idx++; - } - stp->str_index = idx; -} - -int -ofb64_decrypt(int data) -{ - register struct stinfo *stp = &fb[OFB].streams[DIR_DECRYPT-1]; - int idx; - - if (data == -1) { - /* - * Back up one byte. It is assumed that we will - * never back up more than one byte. If we do, this - * may or may not work. - */ - if (stp->str_index) - --stp->str_index; - return(0); - } - - idx = stp->str_index++; - if (idx == sizeof(Block)) { - Block b; - des_ecb_encrypt(&stp->str_feed, &b, stp->str_sched, 1); - memmove((void *)stp->str_feed, (void *)b, sizeof(Block)); - stp->str_index = 1; /* Next time will be 1 */ - idx = 0; /* But now use 0 */ - } - - return(data ^ stp->str_feed[idx]); -} -# endif /* DES_ENCRYPTION */ -# endif /* AUTHENTICATION */ -#endif /* ENCRYPTION */ diff --git a/lib/libtelnet/encrypt.c b/lib/libtelnet/encrypt.c deleted file mode 100644 index 5aed35f2f..000000000 --- a/lib/libtelnet/encrypt.c +++ /dev/null @@ -1,960 +0,0 @@ -/* $NetBSD: encrypt.c,v 1.17 2012/03/21 05:33:27 matt Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#if 0 -static char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; -#else -__RCSID("$NetBSD: encrypt.c,v 1.17 2012/03/21 05:33:27 matt Exp $"); -#endif /* not lint */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifdef ENCRYPTION - -#include -#define ENCRYPT_NAMES -#include - -#include "encrypt.h" -#include "misc.h" - -#include -#ifdef NO_STRING_H -#include -#else -#include -#endif - -/* - * These functions pointers point to the current routines - * for encrypting and decrypting data. - */ -void (*encrypt_output)(unsigned char *, int); -int (*decrypt_input)(int); - -int encrypt_debug_mode = 0; -static int decrypt_mode = 0; -static int encrypt_mode = 0; -static int encrypt_verbose = 0; -static int autoencrypt = 0; -static int autodecrypt = 0; -static int havesessionkey = 0; -static int Server = 0; -static const char *Name = "Noname"; - -#define typemask(x) ((x) > 0 ? 1 << ((x)-1) : 0) - -static long i_support_encrypt = typemask(ENCTYPE_DES_CFB64) - | typemask(ENCTYPE_DES_OFB64); -static long i_support_decrypt = typemask(ENCTYPE_DES_CFB64) - | typemask(ENCTYPE_DES_OFB64); -static long i_wont_support_encrypt = 0; -static long i_wont_support_decrypt = 0; -#define I_SUPPORT_ENCRYPT (i_support_encrypt & ~i_wont_support_encrypt) -#define I_SUPPORT_DECRYPT (i_support_decrypt & ~i_wont_support_decrypt) - -static long remote_supports_encrypt = 0; -static long remote_supports_decrypt = 0; - -static Encryptions encryptions[] = { -#ifdef DES_ENCRYPTION - { "DES_CFB64", ENCTYPE_DES_CFB64, - cfb64_encrypt, - cfb64_decrypt, - cfb64_init, - cfb64_start, - cfb64_is, - cfb64_reply, - cfb64_session, - cfb64_keyid, - cfb64_printsub }, - { "DES_OFB64", ENCTYPE_DES_OFB64, - ofb64_encrypt, - ofb64_decrypt, - ofb64_init, - ofb64_start, - ofb64_is, - ofb64_reply, - ofb64_session, - ofb64_keyid, - ofb64_printsub }, -#endif /* DES_ENCRYPTION */ - { .name = 0 }, -}; - -static unsigned char str_send[64] = { IAC, SB, TELOPT_ENCRYPT, - ENCRYPT_SUPPORT }; -static unsigned char str_suplen = 0; -static unsigned char str_start[72] = { IAC, SB, TELOPT_ENCRYPT }; -static unsigned char str_end[] = { IAC, SB, TELOPT_ENCRYPT, 0, IAC, SE }; - -Encryptions * -findencryption(int type) -{ - Encryptions *ep = encryptions; - - if (!(I_SUPPORT_ENCRYPT & remote_supports_decrypt & typemask(type))) - return(0); - while (ep->type && ep->type != type) - ++ep; - return(ep->type ? ep : 0); -} - -Encryptions * -finddecryption(int type) -{ - Encryptions *ep = encryptions; - - if (!(I_SUPPORT_DECRYPT & remote_supports_encrypt & typemask(type))) - return(0); - while (ep->type && ep->type != type) - ++ep; - return(ep->type ? ep : 0); -} - -#define MAXKEYLEN 64 - -static struct key_info { - unsigned char keyid[MAXKEYLEN]; - int keylen; - int dir; - int *modep; - Encryptions *(*getcrypt)(int); -} ki[2] = { - { { 0 }, 0, DIR_ENCRYPT, &encrypt_mode, findencryption }, - { { 0 }, 0, DIR_DECRYPT, &decrypt_mode, finddecryption }, -}; - -void -encrypt_init(const char *name, int server) -{ - Encryptions *ep = encryptions; - - Name = name; - Server = server; - i_support_encrypt = i_support_decrypt = 0; - remote_supports_encrypt = remote_supports_decrypt = 0; - encrypt_mode = 0; - decrypt_mode = 0; - encrypt_output = 0; - decrypt_input = 0; -#ifdef notdef - encrypt_verbose = !server; -#endif - - str_suplen = 4; - - while (ep->type) { - if (encrypt_debug_mode) - printf(">>>%s: I will support %s\r\n", - Name, ENCTYPE_NAME(ep->type)); - i_support_encrypt |= typemask(ep->type); - i_support_decrypt |= typemask(ep->type); - if ((i_wont_support_decrypt & typemask(ep->type)) == 0) - if ((str_send[str_suplen++] = ep->type) == IAC) - str_send[str_suplen++] = IAC; - if (ep->init) - (*ep->init)(Server); - ++ep; - } - str_send[str_suplen++] = IAC; - str_send[str_suplen++] = SE; -} - -void -encrypt_list_types(void) -{ - Encryptions *ep = encryptions; - - printf("Valid encryption types:\n"); - while (ep->type) { - printf("\t%s (%d)\r\n", ENCTYPE_NAME(ep->type), ep->type); - ++ep; - } -} - -int -EncryptEnable(char *type, char *mode) -{ - if (isprefix(type, "help") || isprefix(type, "?")) { - printf("Usage: encrypt enable [input|output]\n"); - encrypt_list_types(); - return(0); - } - if (EncryptType(type, mode)) - return(EncryptStart(mode)); - return(0); -} - -int -EncryptDisable(char *type, char *mode) -{ - register Encryptions *ep; - int ret = 0; - - if (isprefix(type, "help") || isprefix(type, "?")) { - printf("Usage: encrypt disable [input|output]\n"); - encrypt_list_types(); - } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, - sizeof(Encryptions))) == 0) { - printf("%s: invalid encryption type\n", type); - } else if (Ambiguous(ep)) { - printf("Ambiguous type '%s'\n", type); - } else { - if ((mode == 0) || (isprefix(mode, "input") ? 1 : 0)) { - if (decrypt_mode == ep->type) - EncryptStopInput(); - i_wont_support_decrypt |= typemask(ep->type); - ret = 1; - } - if ((mode == 0) || (isprefix(mode, "output"))) { - if (encrypt_mode == ep->type) - EncryptStopOutput(); - i_wont_support_encrypt |= typemask(ep->type); - ret = 1; - } - if (ret == 0) - printf("%s: invalid encryption mode\n", mode); - } - return(ret); -} - -int -EncryptType(char *type, char *mode) -{ - register Encryptions *ep; - int ret = 0; - - if (isprefix(type, "help") || isprefix(type, "?")) { - printf("Usage: encrypt type [input|output]\n"); - encrypt_list_types(); - } else if ((ep = (Encryptions *)genget(type, (char **)encryptions, - sizeof(Encryptions))) == 0) { - printf("%s: invalid encryption type\n", type); - } else if (Ambiguous(ep)) { - printf("Ambiguous type '%s'\n", type); - } else { - if ((mode == 0) || isprefix(mode, "input")) { - decrypt_mode = ep->type; - i_wont_support_decrypt &= ~typemask(ep->type); - ret = 1; - } - if ((mode == 0) || isprefix(mode, "output")) { - encrypt_mode = ep->type; - i_wont_support_encrypt &= ~typemask(ep->type); - ret = 1; - } - if (ret == 0) - printf("%s: invalid encryption mode\n", mode); - } - return(ret); -} - -int -EncryptStart(char *mode) -{ - register int ret = 0; - if (mode) { - if (isprefix(mode, "input")) - return(EncryptStartInput()); - if (isprefix(mode, "output")) - return(EncryptStartOutput()); - if (isprefix(mode, "help") || isprefix(mode, "?")) { - printf("Usage: encrypt start [input|output]\n"); - return(0); - } - printf("%s: invalid encryption mode 'encrypt start ?' for help\n", mode); - return(0); - } - ret += EncryptStartInput(); - ret += EncryptStartOutput(); - return(ret); -} - -int -EncryptStartInput(void) -{ - if (decrypt_mode) { - encrypt_send_request_start(); - return(1); - } - printf("No previous decryption mode, decryption not enabled\r\n"); - return(0); -} - -int -EncryptStartOutput(void) -{ - if (encrypt_mode) { - encrypt_start_output(encrypt_mode); - return(1); - } - printf("No previous encryption mode, encryption not enabled\r\n"); - return(0); -} - -int -EncryptStop(char *mode) -{ - int ret = 0; - if (mode) { - if (isprefix(mode, "input")) - return(EncryptStopInput()); - if (isprefix(mode, "output")) - return(EncryptStopOutput()); - if (isprefix(mode, "help") || isprefix(mode, "?")) { - printf("Usage: encrypt stop [input|output]\n"); - return(0); - } - printf("%s: invalid encryption mode 'encrypt stop ?' for help\n", mode); - return(0); - } - ret += EncryptStopInput(); - ret += EncryptStopOutput(); - return(ret); -} - -int -EncryptStopInput(void) -{ - encrypt_send_request_end(); - return(1); -} - -int -EncryptStopOutput(void) -{ - encrypt_send_end(); - return(1); -} - -void -encrypt_display(void) -{ - if (encrypt_output) - printf("Currently encrypting output with %s\r\n", - ENCTYPE_NAME(encrypt_mode)); - if (decrypt_input) - printf("Currently decrypting input with %s\r\n", - ENCTYPE_NAME(decrypt_mode)); -} - -int -EncryptStatus(void) -{ - if (encrypt_output) - printf("Currently encrypting output with %s\r\n", - ENCTYPE_NAME(encrypt_mode)); - else if (encrypt_mode) { - printf("Currently output is clear text.\r\n"); - printf("Last encryption mode was %s\r\n", - ENCTYPE_NAME(encrypt_mode)); - } - if (decrypt_input) { - printf("Currently decrypting input with %s\r\n", - ENCTYPE_NAME(decrypt_mode)); - } else if (decrypt_mode) { - printf("Currently input is clear text.\r\n"); - printf("Last decryption mode was %s\r\n", - ENCTYPE_NAME(decrypt_mode)); - } - return 1; -} - -void -encrypt_send_support(void) -{ - if (str_suplen) { - /* - * If the user has requested that decryption start - * immediatly, then send a "REQUEST START" before - * we negotiate the type. - */ - if (!Server && autodecrypt) - encrypt_send_request_start(); - telnet_net_write(str_send, str_suplen); - printsub('>', &str_send[2], str_suplen - 2); - str_suplen = 0; - } -} - -int -EncryptDebug(int on) -{ - if (on < 0) - encrypt_debug_mode ^= 1; - else - encrypt_debug_mode = on; - printf("Encryption debugging %s\r\n", - encrypt_debug_mode ? "enabled" : "disabled"); - return(1); -} - -int -EncryptVerbose(int on) -{ - if (on < 0) - encrypt_verbose ^= 1; - else - encrypt_verbose = on; - printf("Encryption %s verbose\r\n", - encrypt_verbose ? "is" : "is not"); - return(1); -} - -int -EncryptAutoEnc(int on) -{ - encrypt_auto(on); - printf("Automatic encryption of output is %s\r\n", - autoencrypt ? "enabled" : "disabled"); - return(1); -} - -int -EncryptAutoDec(int on) -{ - decrypt_auto(on); - printf("Automatic decryption of input is %s\r\n", - autodecrypt ? "enabled" : "disabled"); - return(1); -} - -/* - * Called when ENCRYPT SUPPORT is received. - */ -void -encrypt_support(unsigned char *typelist, int cnt) -{ - register int type, use_type = 0; - Encryptions *ep; - - /* - * Forget anything the other side has previously told us. - */ - remote_supports_decrypt = 0; - - while (cnt-- > 0) { - type = *typelist++; - if (encrypt_debug_mode) - printf(">>>%s: He is supporting %s (%d)\r\n", - Name, - ENCTYPE_NAME(type), type); - if ((type < ENCTYPE_CNT) && - (I_SUPPORT_ENCRYPT & typemask(type))) { - remote_supports_decrypt |= typemask(type); - if (use_type == 0) - use_type = type; - } - } - if (use_type) { - ep = findencryption(use_type); - if (!ep) - return; - type = ep->start ? (*ep->start)(DIR_ENCRYPT, Server) : 0; - if (encrypt_debug_mode) - printf(">>>%s: (*ep->start)() returned %d\r\n", - Name, type); - if (type < 0) - return; - encrypt_mode = use_type; - if (type == 0) - encrypt_start_output(use_type); - } -} - -void -encrypt_is(unsigned char *data, int cnt) -{ - Encryptions *ep; - register int type, ret; - - if (--cnt < 0) - return; - type = *data++; - if (type < ENCTYPE_CNT) - remote_supports_encrypt |= typemask(type); - if (!(ep = finddecryption(type))) { - if (encrypt_debug_mode) - printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", - Name, - ENCTYPE_NAME_OK(type) - ? ENCTYPE_NAME(type) : "(unknown)", - type); - return; - } - if (!ep->is) { - if (encrypt_debug_mode) - printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", - Name, - ENCTYPE_NAME_OK(type) - ? ENCTYPE_NAME(type) : "(unknown)", - type); - ret = 0; - } else { - ret = (*ep->is)(data, cnt); - if (encrypt_debug_mode) - printf("(*ep->is)(%p, %d) returned %s(%d)\n", data, cnt, - (ret < 0) ? "FAIL " : - (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); - } - if (ret < 0) { - autodecrypt = 0; - } else { - decrypt_mode = type; - if (ret == 0 && autodecrypt) - encrypt_send_request_start(); - } -} - -void -encrypt_reply(unsigned char *data, int cnt) -{ - Encryptions *ep; - register int ret, type; - - if (--cnt < 0) - return; - type = *data++; - if (!(ep = findencryption(type))) { - if (encrypt_debug_mode) - printf(">>>%s: Can't find type %s (%d) for initial negotiation\r\n", - Name, - ENCTYPE_NAME_OK(type) - ? ENCTYPE_NAME(type) : "(unknown)", - type); - return; - } - if (!ep->reply) { - if (encrypt_debug_mode) - printf(">>>%s: No initial negotiation needed for type %s (%d)\r\n", - Name, - ENCTYPE_NAME_OK(type) - ? ENCTYPE_NAME(type) : "(unknown)", - type); - ret = 0; - } else { - ret = (*ep->reply)(data, cnt); - if (encrypt_debug_mode) - printf("(*ep->reply)(%p, %d) returned %s(%d)\n", - data, cnt, - (ret < 0) ? "FAIL " : - (ret == 0) ? "SUCCESS " : "MORE_TO_DO ", ret); - } - if (encrypt_debug_mode) - printf(">>>%s: encrypt_reply returned %d\n", Name, ret); - if (ret < 0) { - autoencrypt = 0; - } else { - encrypt_mode = type; - if (ret == 0 && autoencrypt) - encrypt_start_output(type); - } -} - -/* - * Called when a ENCRYPT START command is received. - */ -void -encrypt_start(unsigned char *data, int cnt) -{ - Encryptions *ep; - - if (!decrypt_mode) { - /* - * Something is wrong. We should not get a START - * command without having already picked our - * decryption scheme. Send a REQUEST-END to - * attempt to clear the channel... - */ - printf("%s: Warning, Cannot decrypt input stream!!!\r\n", Name); - encrypt_send_request_end(); - return; - } - - if ((ep = finddecryption(decrypt_mode)) != NULL) { - decrypt_input = ep->input; - if (encrypt_verbose) - printf("[ Input is now decrypted with type %s ]\r\n", - ENCTYPE_NAME(decrypt_mode)); - if (encrypt_debug_mode) - printf(">>>%s: Start to decrypt input with type %s\r\n", - Name, ENCTYPE_NAME(decrypt_mode)); - } else { - printf("%s: Warning, Cannot decrypt type %s (%d)!!!\r\n", - Name, - ENCTYPE_NAME_OK(decrypt_mode) - ? ENCTYPE_NAME(decrypt_mode) - : "(unknown)", - decrypt_mode); - encrypt_send_request_end(); - } -} - -void -encrypt_session_key(Session_Key *key, int server) -{ - Encryptions *ep = encryptions; - - havesessionkey = 1; - - while (ep->type) { - if (ep->session) - (*ep->session)(key, server); -#ifdef notdef - if (!encrypt_output && autoencrypt && !server) - encrypt_start_output(ep->type); - if (!decrypt_input && autodecrypt && !server) - encrypt_send_request_start(); -#endif - ++ep; - } -} - -/* - * Called when ENCRYPT END is received. - */ -void -encrypt_end(void) -{ - decrypt_input = 0; - if (encrypt_debug_mode) - printf(">>>%s: Input is back to clear text\r\n", Name); - if (encrypt_verbose) - printf("[ Input is now clear text ]\r\n"); -} - -/* - * Called when ENCRYPT REQUEST-END is received. - */ -void -encrypt_request_end(void) -{ - encrypt_send_end(); -} - -/* - * Called when ENCRYPT REQUEST-START is received. If we receive - * this before a type is picked, then that indicates that the - * other side wants us to start encrypting data as soon as we - * can. - */ -void -encrypt_request_start(unsigned char *data, int cnt) -{ - if (encrypt_mode == 0) { - if (Server) - autoencrypt = 1; - return; - } - encrypt_start_output(encrypt_mode); -} - -static unsigned char str_keyid[(MAXKEYLEN*2)+5] = { IAC, SB, TELOPT_ENCRYPT }; - -void -encrypt_enc_keyid(unsigned char *keyid, int len) -{ - encrypt_keyid(&ki[1], keyid, len); -} - -void -encrypt_dec_keyid(unsigned char *keyid, int len) -{ - encrypt_keyid(&ki[0], keyid, len); -} - -void -encrypt_keyid(struct key_info *kp, unsigned char *keyid, int len) -{ - Encryptions *ep; - int dir = kp->dir; - register int ret = 0; - - if (!(ep = (*kp->getcrypt)(*kp->modep))) { - if (len == 0) - return; - kp->keylen = 0; - } else if (len == 0) { - /* - * Empty option, indicates a failure. - */ - if (kp->keylen == 0) - return; - kp->keylen = 0; - if (ep->keyid) - (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); - - } else if ((size_t)len > sizeof(kp->keyid)) { - return; - } else if ((len != kp->keylen) || - (memcmp(keyid, kp->keyid, len) != 0)) { - /* - * Length or contents are different - */ - kp->keylen = len; - memmove(kp->keyid, keyid, len); - if (ep->keyid) - (void)(*ep->keyid)(dir, kp->keyid, &kp->keylen); - } else { - if (ep->keyid) - ret = (*ep->keyid)(dir, kp->keyid, &kp->keylen); - if ((ret == 0) && (dir == DIR_ENCRYPT) && autoencrypt) - encrypt_start_output(*kp->modep); - return; - } - - encrypt_send_keyid(dir, kp->keyid, kp->keylen, 0); -} - -void -encrypt_send_keyid(int dir, const unsigned char *keyid, int keylen, int saveit) -{ - unsigned char *strp; - - str_keyid[3] = (dir == DIR_ENCRYPT) - ? ENCRYPT_ENC_KEYID : ENCRYPT_DEC_KEYID; - if (saveit) { - struct key_info *kp = &ki[(dir == DIR_ENCRYPT) ? 0 : 1]; - memmove(kp->keyid, keyid, keylen); - kp->keylen = keylen; - } - - for (strp = &str_keyid[4]; keylen > 0; --keylen) { - if ((*strp++ = *keyid++) == IAC) - *strp++ = IAC; - } - *strp++ = IAC; - *strp++ = SE; - telnet_net_write(str_keyid, strp - str_keyid); - printsub('>', &str_keyid[2], strp - str_keyid - 2); -} - -void -encrypt_auto(int on) -{ - if (on < 0) - autoencrypt ^= 1; - else - autoencrypt = on ? 1 : 0; -} - -void -decrypt_auto(int on) -{ - if (on < 0) - autodecrypt ^= 1; - else - autodecrypt = on ? 1 : 0; -} - -void -encrypt_start_output(int type) -{ - Encryptions *ep; - register unsigned char *p; - register int i; - - if (!(ep = findencryption(type))) { - if (encrypt_debug_mode) { - printf(">>>%s: Can't encrypt with type %s (%d)\r\n", - Name, - ENCTYPE_NAME_OK(type) - ? ENCTYPE_NAME(type) : "(unknown)", - type); - } - return; - } - if (ep->start) { - i = (*ep->start)(DIR_ENCRYPT, Server); - if (encrypt_debug_mode) { - printf(">>>%s: Encrypt start: %s (%d) %s\r\n", - Name, - (i < 0) ? "failed" : - "initial negotiation in progress", - i, ENCTYPE_NAME(type)); - } - if (i) - return; - } - p = str_start + 3; - *p++ = ENCRYPT_START; - for (i = 0; i < ki[0].keylen; ++i) { - if ((*p++ = ki[0].keyid[i]) == IAC) - *p++ = IAC; - } - *p++ = IAC; - *p++ = SE; - telnet_net_write(str_start, p - str_start); - net_encrypt(); - printsub('>', &str_start[2], p - &str_start[2]); - /* - * If we are already encrypting in some mode, then - * encrypt the ring (which includes our request) in - * the old mode, mark it all as "clear text" and then - * switch to the new mode. - */ - encrypt_output = ep->output; - encrypt_mode = type; - if (encrypt_debug_mode) - printf(">>>%s: Started to encrypt output with type %s\r\n", - Name, ENCTYPE_NAME(type)); - if (encrypt_verbose) - printf("[ Output is now encrypted with type %s ]\r\n", - ENCTYPE_NAME(type)); -} - -void -encrypt_send_end(void) -{ - if (!encrypt_output) - return; - - str_end[3] = ENCRYPT_END; - telnet_net_write(str_end, sizeof(str_end)); - net_encrypt(); - printsub('>', &str_end[2], sizeof(str_end) - 2); - /* - * Encrypt the output buffer now because it will not be done by - * netflush... - */ - encrypt_output = 0; - if (encrypt_debug_mode) - printf(">>>%s: Output is back to clear text\r\n", Name); - if (encrypt_verbose) - printf("[ Output is now clear text ]\r\n"); -} - -void -encrypt_send_request_start(void) -{ - register unsigned char *p; - register int i; - - p = &str_start[3]; - *p++ = ENCRYPT_REQSTART; - for (i = 0; i < ki[1].keylen; ++i) { - if ((*p++ = ki[1].keyid[i]) == IAC) - *p++ = IAC; - } - *p++ = IAC; - *p++ = SE; - telnet_net_write(str_start, p - str_start); - printsub('>', &str_start[2], p - &str_start[2]); - if (encrypt_debug_mode) - printf(">>>%s: Request input to be encrypted\r\n", Name); -} - -void -encrypt_send_request_end(void) -{ - str_end[3] = ENCRYPT_REQEND; - telnet_net_write(str_end, sizeof(str_end)); - printsub('>', &str_end[2], sizeof(str_end) - 2); - - if (encrypt_debug_mode) - printf(">>>%s: Request input to be clear text\r\n", Name); -} - -void -encrypt_wait(void) -{ - if (encrypt_debug_mode) - printf(">>>%s: in encrypt_wait\r\n", Name); - if (!havesessionkey || !(I_SUPPORT_ENCRYPT & remote_supports_decrypt)) - return; - while (autoencrypt && !encrypt_output) - if (telnet_spin()) - return; -} - -void -encrypt_debug(int mode) -{ - encrypt_debug_mode = mode; -} - -void -encrypt_gen_printsub(unsigned char *data, int cnt, - unsigned char *buf, int buflen) -{ - char tbuf[16], *cp; - - cnt -= 2; - data += 2; - buf[buflen-1] = '\0'; - buf[buflen-2] = '*'; - buflen -= 2; - for (; cnt > 0; cnt--, data++) { - snprintf(tbuf, sizeof(tbuf), " %d", *data); - for (cp = tbuf; *cp && buflen > 0; --buflen) - *buf++ = *cp++; - if (buflen <= 0) - return; - } - *buf = '\0'; -} - -void -encrypt_printsub(unsigned char *data, int cnt, - unsigned char *buf, int buflen) -{ - Encryptions *ep; - register int type = data[1]; - - for (ep = encryptions; ep->type && ep->type != type; ep++) - ; - - if (ep->printsub) - (*ep->printsub)(data, cnt, buf, buflen); - else - encrypt_gen_printsub(data, cnt, buf, buflen); -} -#endif /* ENCRYPTION */ diff --git a/lib/libtelnet/encrypt.h b/lib/libtelnet/encrypt.h deleted file mode 100644 index 570b83a92..000000000 --- a/lib/libtelnet/encrypt.h +++ /dev/null @@ -1,101 +0,0 @@ -/* $NetBSD: encrypt.h,v 1.9 2012/01/09 15:25:33 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)encrypt.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifdef ENCRYPTION -#include - -# ifndef __ENCRYPTION__ -# define __ENCRYPTION__ - -#define DIR_DECRYPT 1 -#define DIR_ENCRYPT 2 - -#define Block des_cblock -typedef unsigned char *BlockT; -#define Schedule des_key_schedule - -#define VALIDKEY(key) ( key[0] | key[1] | key[2] | key[3] | \ - key[4] | key[5] | key[6] | key[7]) - -#define SAMEKEY(k1, k2) (!bcmp((void *)k1, (void *)k2, sizeof(Block))) - -typedef struct { - short type; - int length; - unsigned char *data; -} Session_Key; - - -typedef struct { - const char *name; - int type; - void (*output)(unsigned char *, int); - int (*input)(int); - void (*init)(int); - int (*start)(int, int); - int (*is)(unsigned char *, int); - int (*reply)(unsigned char *, int); - void (*session)(Session_Key *, int); - int (*keyid)(int, unsigned char *, int *); - void (*printsub)(unsigned char *, int, unsigned char *, int); -} Encryptions; - -#define SK_DES 1 /* Matched Kerberos v5 KEYTYPE_DES */ - -#include "enc-proto.h" - -extern int encrypt_debug_mode; -extern int (*decrypt_input)(int); -extern void (*encrypt_output)(unsigned char *, int); -# endif /* __ENCRYPTION__ */ -#endif /* ENCRYPTION */ diff --git a/lib/libtelnet/genget.c b/lib/libtelnet/genget.c deleted file mode 100644 index 49010aa9e..000000000 --- a/lib/libtelnet/genget.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $NetBSD: genget.c,v 1.13 2012/03/21 05:33:27 matt Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)genget.c 8.2 (Berkeley) 5/30/95"; -#else -__RCSID("$NetBSD: genget.c,v 1.13 2012/03/21 05:33:27 matt Exp $"); -#endif -#endif /* not lint */ - - -#include -#include "misc.h" - -#define LOWER(x) (isupper((unsigned char)x) ? tolower((unsigned char)x) : (x)) -/* - * The prefix function returns 0 if *s1 is not a prefix - * of *s2. If *s1 exactly matches *s2, the negative of - * the length is returned. If *s1 is a prefix of *s2, - * the length of *s1 is returned. - */ -int -isprefix(char *s1, const char *s2) -{ - char *os1; - char c1, c2; - - if (*s1 == '\0') - return(-1); - os1 = s1; - c1 = *s1; - c2 = *s2; - while (LOWER(c1) == LOWER(c2)) { - if (c1 == '\0') - break; - c1 = *++s1; - c2 = *++s2; - } - return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1))); -} - -static char *ambiguous; /* special return value for command routines */ - -char ** -genget( char *name, /* name to match */ - char **table, /* name entry in table */ - int stlen) -{ - register char **c, **found; - register int n; - - if (name == 0) - return 0; - - found = 0; - for (c = table; *c != 0; c = (char **)((char *)c + stlen)) { - if ((n = isprefix(name, *c)) == 0) - continue; - if (n < 0) /* exact match */ - return(c); - if (found) - return(&ambiguous); - found = c; - } - return(found); -} - -/* - * Function call version of Ambiguous() - */ -int -Ambiguous(void *s) -{ - return(s == &ambiguous); -} diff --git a/lib/libtelnet/getent.c b/lib/libtelnet/getent.c deleted file mode 100644 index 566c792f4..000000000 --- a/lib/libtelnet/getent.c +++ /dev/null @@ -1,76 +0,0 @@ -/* $NetBSD: getent.c,v 1.11 2012/03/21 05:33:27 matt Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)getent.c 8.2 (Berkeley) 12/15/93"; -#else -__RCSID("$NetBSD: getent.c,v 1.11 2012/03/21 05:33:27 matt Exp $"); -#endif -#endif /* not lint */ - -#include -#include "misc-proto.h" - -static char *area; - -int getent(char *, char *); -char *getstr(char *, char **); - -/*ARGSUSED*/ -int -getent(char *cp, char *name) -{ -#ifdef HAS_CGETENT - const char *dba[2]; - - dba[0] = "/etc/gettytab"; - dba[1] = 0; - return((cgetent(&area, dba, name) == 0) ? 1 : 0); -#else - return(0); -#endif -} - -#ifndef SOLARIS -/*ARGSUSED*/ -char * -getstr(char *id, char **cpp) -{ -# ifdef HAS_CGETENT - char *answer; - return((cgetstr(area, id, &answer) > 0) ? answer : 0); -# else - return(0); -# endif -} -#endif diff --git a/lib/libtelnet/kerberos5.c b/lib/libtelnet/kerberos5.c deleted file mode 100644 index 39ab14472..000000000 --- a/lib/libtelnet/kerberos5.c +++ /dev/null @@ -1,731 +0,0 @@ -/* $NetBSD: kerberos5.c,v 1.20 2014/04/26 22:10:40 joerg Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifdef KRB5 -#include -#include -#include -#include -#include -#include -#include -#include -#define Authenticator k5_Authenticator -#include -#undef Authenticator -/* #include */ - -#include "encrypt.h" -#include "auth.h" -#include "misc.h" - -extern int net; - -int forward_flags; /* Flags get set in telnet/main.c on -f and -F */ -int got_forwarded_creds;/* Tell telnetd to pass -F or -f to login. */ - -int require_hwpreauth; - -const char *get_krb5_err_text(krb5_context, krb5_error_code); -void kerberos5_forward(Authenticator *); - -static unsigned char str_data[1024] = {IAC, SB, TELOPT_AUTHENTICATION, 0, - AUTHTYPE_KERBEROS_V5,}; - -#define KRB_AUTH 0 /* Authentication data follows */ -#define KRB_REJECT 1 /* Rejected (reason might follow) */ -#define KRB_ACCEPT 2 /* Accepted */ -#define KRB_RESPONSE 3 /* Response for mutual auth. */ - -#define KRB_FORWARD 4 /* Forwarded credentials follow */ -#define KRB_FORWARD_ACCEPT 5 /* Forwarded credentials accepted */ -#define KRB_FORWARD_REJECT 6 /* Forwarded credentials rejected */ - -static krb5_data auth; -static krb5_ticket *ticket; - -krb5_context telnet_context; -static krb5_auth_context auth_context; - -static int -Data(Authenticator *ap, int type, const void *d, int c) -{ - unsigned char *p = str_data + 4; - const unsigned char *cd = (const unsigned char *) d; - - if (c == -1) - c = strlen(cd); - - if (auth_debug_mode) { - printf("%s:%d: [%d] (%d)", - str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", - str_data[3], - type, c); - printd(d, c); - printf("\r\n"); - } - *p++ = ap->type; - *p++ = ap->way; - *p++ = type; - while (c-- > 0) { - if ((*p++ = *cd++) == IAC) - *p++ = IAC; - } - *p++ = IAC; - *p++ = SE; - if (str_data[3] == TELQUAL_IS) - printsub('>', &str_data[2], p - &str_data[2]); - return (telnet_net_write(str_data, p - str_data)); -} - -const char * -get_krb5_err_text(krb5_context ctx, krb5_error_code ret) -{ - static const char *str = NULL; - - if (str) - krb5_free_error_message(ctx, str); - - str = krb5_get_error_message(ctx, ret); - - if (str != NULL) - return str; - - return "unknown"; -} - -int -kerberos5_init(Authenticator *ap, int server) -{ - krb5_error_code ret; - - if (telnet_context == 0) { - ret = krb5_init_context(&telnet_context); - if (ret) - return 0; - } - - if (server) { - krb5_keytab kt; - krb5_kt_cursor cursor; - - ret = krb5_kt_default(telnet_context, &kt); - if (ret) - return 0; - - ret = krb5_kt_start_seq_get(telnet_context, kt, &cursor); - if (ret) { - krb5_kt_close(telnet_context, kt); - return 0; - } - krb5_kt_end_seq_get(telnet_context, kt, &cursor); - krb5_kt_close(telnet_context, kt); - - str_data[3] = TELQUAL_REPLY; - } else - str_data[3] = TELQUAL_IS; - return (1); -} - -int -kerberos5_send(Authenticator *ap) -{ - krb5_error_code ret; - krb5_ccache ccache; - int ap_opts; - krb5_data cksum_data; - char foo[2]; - - printf("[ Trying KERBEROS5 ... ]\r\n"); - - if (!UserNameRequested) { - if (auth_debug_mode) { - printf("Kerberos V5: no user name supplied\r\n"); - } - return (0); - } - ret = krb5_cc_default(telnet_context, &ccache); - if (ret) { - if (auth_debug_mode) { - printf( - "Kerberos V5: could not get default ccache: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - } - return (0); - } - if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) - ap_opts = AP_OPTS_MUTUAL_REQUIRED; - else - ap_opts = 0; - - ap_opts |= AP_OPTS_USE_SUBKEY; - - ret = krb5_auth_con_init(telnet_context, &auth_context); - if (ret) { - if (auth_debug_mode) { - printf( - "Kerberos V5: krb5_auth_con_init failed: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - } - return (0); - } - ret = krb5_auth_con_setaddrs_from_fd(telnet_context, - auth_context, &net); - if (ret) { - if (auth_debug_mode) { - printf("Kerberos V5: " - "krb5_auth_con_setaddrs_from_fd failed: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - } - return (0); - } - krb5_auth_con_setkeytype(telnet_context, auth_context, - ETYPE_DES_CBC_CRC); - - foo[0] = ap->type; - foo[1] = ap->way; - - cksum_data.length = sizeof(foo); - cksum_data.data = foo; - ret = krb5_mk_req(telnet_context, &auth_context, ap_opts, "host", - RemoteHostName, &cksum_data, ccache, &auth); - if (ret) { - if (1 || auth_debug_mode) { - printf("Kerberos V5: mk_req failed (%s)\r\n", - get_krb5_err_text(telnet_context, ret)); - } - return (0); - } - - if (!auth_sendname((unsigned char *) UserNameRequested, - strlen(UserNameRequested))) { - if (auth_debug_mode) - printf("Not enough room for user name\r\n"); - return (0); - } - if (!Data(ap, KRB_AUTH, auth.data, auth.length)) { - if (auth_debug_mode) - printf("Not enough room for authentication data\r\n"); - return (0); - } - if (auth_debug_mode) { - printf("Sent Kerberos V5 credentials to server\r\n"); - } - return (1); -} - -void -kerberos5_is(Authenticator * ap, unsigned char *data, int cnt) -{ - krb5_error_code ret; - krb5_data outbuf; - krb5_keyblock *key_block; - char *name; - krb5_principal server; - int zero = 0; - - if (cnt-- < 1) - return; - switch (*data++) { - case KRB_AUTH: - auth.data = (char *) data; - auth.length = cnt; - - auth_context = NULL; - - ret = krb5_auth_con_init(telnet_context, &auth_context); - if (ret) { - Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: krb5_auth_con_init failed (%s)\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - ret = krb5_auth_con_setaddrs_from_fd(telnet_context, - auth_context, &zero); - if (ret) { - Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: " - "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - ret = krb5_sock_to_principal(telnet_context, 0, "host", - KRB5_NT_SRV_HST, &server); - if (ret) { - Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: " - "krb5_sock_to_principal failed (%s)\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - ret = krb5_rd_req(telnet_context, &auth_context, &auth, - server, NULL, NULL, &ticket); - krb5_free_principal(telnet_context, server); - - if (ret) { - char *errbuf; - - asprintf(&errbuf, - "Read req failed: %s", - get_krb5_err_text(telnet_context, ret)); - Data(ap, KRB_REJECT, errbuf, -1); - if (auth_debug_mode) - printf("%s\r\n", errbuf); - free(errbuf); - return; - } { - char foo[2]; - - foo[0] = ap->type; - foo[1] = ap->way; - - ret = krb5_verify_authenticator_checksum(telnet_context, - auth_context, foo, sizeof(foo)); - - if (ret) { - char *errbuf; - asprintf(&errbuf, "Bad checksum: %s", - get_krb5_err_text(telnet_context, ret)); - Data(ap, KRB_REJECT, errbuf, -1); - if (auth_debug_mode) - printf("%s\r\n", errbuf); - free(errbuf); - return; - } - } - ret = krb5_auth_con_getremotesubkey(telnet_context, - auth_context, &key_block); - - if (ret) { - Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: " - "krb5_auth_con_getremotesubkey failed (%s)\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - if (key_block == NULL) { - ret = krb5_auth_con_getkey(telnet_context, - auth_context, - &key_block); - } - if (ret) { - Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: " - "krb5_auth_con_getkey failed (%s)\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - if (key_block == NULL) { - Data(ap, KRB_REJECT, "no subkey received", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: " - "krb5_auth_con_getremotesubkey returned NULL key\r\n"); - return; - } - if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { - ret = krb5_mk_rep(telnet_context, - auth_context, &outbuf); - if (ret) { - Data(ap, KRB_REJECT, - "krb5_mk_rep failed", -1); - auth_finished(ap, AUTH_REJECT); - if (auth_debug_mode) - printf("Kerberos V5: " - "krb5_mk_rep failed (%s)\r\n", - get_krb5_err_text(telnet_context, - ret)); - krb5_free_keyblock(telnet_context, key_block); - return; - } - Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length); - } - if (krb5_unparse_name(telnet_context, ticket->client, &name)) - name = 0; - - if (UserNameRequested && krb5_kuserok(telnet_context, - ticket->client, UserNameRequested)) { - Data(ap, KRB_ACCEPT, name ? name : "", name ? -1 : 0); - if (auth_debug_mode) { - printf("Kerberos5 identifies him as ``%s''\r\n", - name ? name : ""); - } - if (key_block->keytype == ETYPE_DES_CBC_MD5 || - key_block->keytype == ETYPE_DES_CBC_MD4 || - key_block->keytype == ETYPE_DES_CBC_CRC) { - Session_Key skey; - - skey.type = SK_DES; - skey.length = 8; - skey.data = key_block->keyvalue.data; - encrypt_session_key(&skey, 0); - } - } else { - char *msg; - - asprintf(&msg, "user `%s' is not authorized to " - "login as `%s'", - name ? name : "", - UserNameRequested ? UserNameRequested : ""); - if (msg == NULL) - Data(ap, KRB_REJECT, NULL, 0); - else { - Data(ap, KRB_REJECT, (void *) msg, -1); - free(msg); - } - auth_finished(ap, AUTH_REJECT); - krb5_free_keyblock(telnet_context, key_block); - break; - } - auth_finished(ap, AUTH_USER); - krb5_free_keyblock(telnet_context, key_block); - break; - case KRB_FORWARD:{ - struct passwd pws, *pwd; - char pwbuf[1024]; - char ccname[1024]; /* XXX */ - krb5_data inbuf; - krb5_ccache ccache; - inbuf.data = (char *) data; - inbuf.length = cnt; - - if (getpwnam_r(UserNameRequested, &pws, pwbuf, - sizeof(pwbuf), &pwd) != 0 || pwd == NULL) - break; - - snprintf(ccname, sizeof(ccname), - "FILE:/tmp/krb5cc_%u", pwd->pw_uid); - - ret = krb5_cc_resolve(telnet_context, ccname, &ccache); - if (ret) { - if (auth_debug_mode) - printf("Kerberos V5: could not get ccache: %s\r\n", - get_krb5_err_text(telnet_context, - ret)); - break; - } - ret = krb5_cc_initialize(telnet_context, ccache, - ticket->client); - if (ret) { - if (auth_debug_mode) - printf("Kerberos V5: could not init ccache: %s\r\n", - get_krb5_err_text(telnet_context, - ret)); - break; - } - ret = krb5_rd_cred2(telnet_context, auth_context, - ccache, &inbuf); - if (ret) { - char *errbuf; - - asprintf(&errbuf, - "Read forwarded creds failed: %s", - get_krb5_err_text(telnet_context, ret)); - if (errbuf == NULL) - Data(ap, KRB_FORWARD_REJECT, NULL, 0); - else - Data(ap, KRB_FORWARD_REJECT, errbuf, -1); - if (auth_debug_mode) - printf("Could not read forwarded credentials: %s\r\n", - errbuf); - free(errbuf); - } else - Data(ap, KRB_FORWARD_ACCEPT, 0, 0); - chown(ccname + 5, pwd->pw_uid, -1); - if (auth_debug_mode) - printf("Forwarded credentials obtained\r\n"); - break; - } - default: - if (auth_debug_mode) - printf("Unknown Kerberos option %d\r\n", data[-1]); - Data(ap, KRB_REJECT, 0, 0); - break; - } -} - -void -kerberos5_reply(Authenticator * ap, unsigned char *data, int cnt) -{ - static int mutual_complete = 0; - - if (cnt-- < 1) - return; - switch (*data++) { - case KRB_REJECT: - if (cnt > 0) { - printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n", - cnt, data); - } else - printf("[ Kerberos V5 refuses authentication ]\r\n"); - auth_send_retry(); - return; - case KRB_ACCEPT:{ - krb5_error_code ret; - Session_Key skey; - krb5_keyblock *keyblock; - - if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && - !mutual_complete) { - printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n"); - auth_send_retry(); - return; - } - if (cnt) - printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data); - else - printf("[ Kerberos V5 accepts you ]\r\n"); - - ret = krb5_auth_con_getlocalsubkey(telnet_context, - auth_context, &keyblock); - if (ret) - ret = krb5_auth_con_getkey(telnet_context, - auth_context, &keyblock); - if (ret) { - printf("[ krb5_auth_con_getkey: %s ]\r\n", - get_krb5_err_text(telnet_context, ret)); - auth_send_retry(); - return; - } - skey.type = SK_DES; - skey.length = 8; - skey.data = keyblock->keyvalue.data; - encrypt_session_key(&skey, 0); - krb5_free_keyblock(telnet_context, keyblock); - auth_finished(ap, AUTH_USER); - if (forward_flags & OPTS_FORWARD_CREDS) - kerberos5_forward(ap); - break; - } - case KRB_RESPONSE: - if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { - /* the rest of the reply should contain a krb_ap_rep */ - krb5_ap_rep_enc_part *reply; - krb5_data inbuf; - krb5_error_code ret; - - inbuf.length = cnt; - inbuf.data = (char *) data; - - ret = krb5_rd_rep(telnet_context, - auth_context, &inbuf, &reply); - if (ret) { - printf("[ Mutual authentication failed: %s ]\r\n", - get_krb5_err_text(telnet_context, ret)); - auth_send_retry(); - return; - } - krb5_free_ap_rep_enc_part(telnet_context, reply); - mutual_complete = 1; - } - return; - case KRB_FORWARD_ACCEPT: - printf("[ Kerberos V5 accepted forwarded credentials ]\r\n"); - return; - case KRB_FORWARD_REJECT: - printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n", - cnt, data); - return; - default: - if (auth_debug_mode) - printf("Unknown Kerberos option %d\r\n", data[-1]); - return; - } -} - -int -kerberos5_status(Authenticator *ap, char *name, size_t l, int level) -{ - if (level < AUTH_USER) - return (level); - - if (UserNameRequested && - krb5_kuserok(telnet_context, ticket->client, UserNameRequested)) { - strlcpy(name, UserNameRequested, l); - return (AUTH_VALID); - } else - return (AUTH_USER); -} -#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} -#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} - -void -kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen) -{ - int i; - - buf[buflen - 1] = '\0'; /* make sure its NULL terminated */ - buflen -= 1; - - switch (data[3]) { - case KRB_REJECT: /* Rejected (reason might follow) */ - strlcpy((char *) buf, " REJECT ", buflen); - goto common; - - case KRB_ACCEPT: /* Accepted (name might follow) */ - strlcpy((char *) buf, " ACCEPT ", buflen); -common: - BUMP(buf, buflen); - if (cnt <= 4) - break; - ADDC(buf, buflen, '"'); - for (i = 4; i < cnt; i++) - ADDC(buf, buflen, data[i]); - ADDC(buf, buflen, '"'); - ADDC(buf, buflen, '\0'); - break; - - - case KRB_AUTH: /* Authentication data follows */ - strlcpy((char *) buf, " AUTH", buflen); - goto common2; - - case KRB_RESPONSE: - strlcpy((char *) buf, " RESPONSE", buflen); - goto common2; - - case KRB_FORWARD: /* Forwarded credentials follow */ - strlcpy((char *) buf, " FORWARD", buflen); - goto common2; - - case KRB_FORWARD_ACCEPT: /* Forwarded credentials accepted */ - strlcpy((char *) buf, " FORWARD_ACCEPT", buflen); - goto common2; - - case KRB_FORWARD_REJECT: /* Forwarded credentials rejected */ - /* (reason might follow) */ - strlcpy((char *) buf, " FORWARD_REJECT", buflen); - goto common2; - - default: - snprintf(buf, buflen, " %d (unknown)", data[3]); -common2: - BUMP(buf, buflen); - for (i = 4; i < cnt; i++) { - snprintf(buf, buflen, " %d", data[i]); - BUMP(buf, buflen); - } - break; - } -} - -void -kerberos5_forward(Authenticator * ap) -{ - krb5_error_code ret; - krb5_ccache ccache; - krb5_creds creds; - krb5_kdc_flags flags; - krb5_data out_data; - krb5_principal principal; - - ret = krb5_cc_default(telnet_context, &ccache); - if (ret) { - if (auth_debug_mode) - printf("KerberosV5: could not get default ccache: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - ret = krb5_cc_get_principal(telnet_context, ccache, &principal); - if (ret) { - if (auth_debug_mode) - printf("KerberosV5: could not get principal: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - memset(&creds, 0, sizeof(creds)); - - creds.client = principal; - - ret = krb5_build_principal(telnet_context, &creds.server, - strlen(principal->realm), principal->realm, "krbtgt", - principal->realm, NULL); - - if (ret) { - if (auth_debug_mode) - printf("KerberosV5: could not get principal: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - creds.times.endtime = 0; - - flags.i = 0; - flags.b.forwarded = 1; - if (forward_flags & OPTS_FORWARDABLE_CREDS) - flags.b.forwardable = 1; - - ret = krb5_get_forwarded_creds(telnet_context, auth_context, - ccache, flags.i, RemoteHostName, &creds, &out_data); - if (ret) { - if (auth_debug_mode) - printf("Kerberos V5: error getting forwarded creds: %s\r\n", - get_krb5_err_text(telnet_context, ret)); - return; - } - if (!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { - if (auth_debug_mode) - printf("Not enough room for authentication data\r\n"); - } else { - if (auth_debug_mode) - printf("Forwarded local Kerberos V5 credentials to server\r\n"); - } -} -#endif /* KRB5 */ diff --git a/lib/libtelnet/key-proto.h b/lib/libtelnet/key-proto.h deleted file mode 100644 index 038e031ed..000000000 --- a/lib/libtelnet/key-proto.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $NetBSD: key-proto.h,v 1.6 2005/02/06 05:53:07 perry Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)key-proto.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifndef __KEY_PROTO__ -#define __KEY_PROTO__ - -#include - -int key_file_exists(void); -void key_lookup(unsigned char *, Block); -void key_stream_init(Block, Block, int); -unsigned char key_stream(int, int); -#endif diff --git a/lib/libtelnet/misc-proto.h b/lib/libtelnet/misc-proto.h deleted file mode 100644 index 4d3d52e23..000000000 --- a/lib/libtelnet/misc-proto.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $NetBSD: misc-proto.h,v 1.10 2005/02/06 05:53:07 perry Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)misc-proto.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * Copyright (C) 1990 by the Massachusetts Institute of Technology - * - * Export of this software from the United States of America is assumed - * to require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ - -#ifndef __MISC_PROTO__ -#define __MISC_PROTO__ - -#include - -void auth_encrypt_init(const char *, const char *, const char *, int); -void auth_encrypt_user(const char *); -void auth_encrypt_connect(int); -void printd(const unsigned char *, int); - -/* - * These functions are imported from the application - */ -int telnet_net_write(unsigned char *, int); -void net_encrypt(void); -int telnet_spin(void); -char *telnet_getenv(char *); -char *telnet_gets(char *, char *, int, int); -#endif diff --git a/lib/libtelnet/misc.c b/lib/libtelnet/misc.c deleted file mode 100644 index 32904a040..000000000 --- a/lib/libtelnet/misc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: misc.c,v 1.13 2012/03/21 05:33:27 matt Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/4/93"; -#else -__RCSID("$NetBSD: misc.c,v 1.13 2012/03/21 05:33:27 matt Exp $"); -#endif -#endif /* not lint */ - -#include -#include -#include -#include "misc.h" -#include "auth.h" -#include "encrypt.h" - -const char *RemoteHostName; -const char *LocalHostName; -char *UserNameRequested = 0; -int ConnectedCount = 0; - -void -auth_encrypt_init(const char *local, const char *remote, const char *name, - int server) -{ - RemoteHostName = remote; - LocalHostName = local; -#ifdef AUTHENTICATION - auth_init(name, server); -#endif -#ifdef ENCRYPTION - encrypt_init(name, server); -#endif /* ENCRYPTION */ - if (UserNameRequested) { - free(UserNameRequested); - UserNameRequested = 0; - } -} - -void -auth_encrypt_user(const char *name) -{ - if (UserNameRequested) - free(UserNameRequested); - UserNameRequested = name ? strdup(name) : 0; -} - -void -auth_encrypt_connect(int cnt) -{ -} - -void -printd(const unsigned char *data, int cnt) -{ - if (cnt > 16) - cnt = 16; - while (cnt-- > 0) { - printf(" %02x", *data); - ++data; - } -} diff --git a/lib/libtelnet/misc.h b/lib/libtelnet/misc.h deleted file mode 100644 index 72116505e..000000000 --- a/lib/libtelnet/misc.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $NetBSD: misc.h,v 1.9 2012/01/09 15:25:34 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)misc.h 8.1 (Berkeley) 6/4/93 - */ - -__BEGIN_DECLS -extern char *UserNameRequested; -extern const char *LocalHostName; -extern const char *RemoteHostName; -extern int ConnectedCount; -extern int ReservedPort; - -int isprefix(char *, const char *); -char **genget(char *, char **, int); -int Ambiguous(void *); -__END_DECLS - -#include "misc-proto.h" diff --git a/lib/libtelnet/pk.c b/lib/libtelnet/pk.c deleted file mode 100644 index 75d009b3d..000000000 --- a/lib/libtelnet/pk.c +++ /dev/null @@ -1,292 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * Dave Safford. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include - -#ifdef notdef -__FBSDID("$FreeBSD: src/contrib/telnet/libtelnet/pk.c,v 1.10 2002/08/22 06:19:07 nsayer Exp $"); -#else -__RCSID("$NetBSD: pk.c,v 1.4 2005/02/19 22:55:35 christos Exp $"); -#endif - -/* public key routines */ -/* functions: - genkeys(char *public, char *secret) - common_key(char *secret, char *public, desData *deskey) - pk_encode(char *in, *out, DesData *deskey); - pk_decode(char *in, *out, DesData *deskey); - where - char public[HEXKEYBYTES + 1]; - char secret[HEXKEYBYTES + 1]; - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "pk.h" - -static void adjust(char *, const char *); - -/* - * Choose top 128 bits of the common key to use as our idea key. - */ -static void -extractideakey(BIGNUM *ck, IdeaData *ideakey) -{ - BIGNUM *a = BN_new(); - BIGNUM *z = BN_new(); - BIGNUM *base = BN_new(); - BN_CTX *ctx = BN_CTX_new(); - size_t i; - char *k; - - (void)BN_zero(a); - (void)BN_zero(z); - (void)BN_set_word(base, 1 << 8); - BN_add(a, ck, z); - - for (i = 0; i < ((KEYSIZE - 128) / 8); i++) - BN_div(a, z, a, base, ctx); - - k = (char *)(void *)ideakey; - for (i = 0; i < 16; i++) { - BN_div(a, z, a, base, ctx); - *k++ = (char)BN_get_word(z); - } - - BN_CTX_free(ctx); - BN_free(base); - BN_free(z); - BN_free(a); -} - -/* - * Choose middle 64 bits of the common key to use as our des key, possibly - * overwriting the lower order bits by setting parity. - */ -static void -extractdeskey(BIGNUM *ck, DesData *deskey) -{ - BIGNUM *a = BN_new(); - BIGNUM *z = BN_new(); - BIGNUM *base = BN_new(); - BN_CTX *ctx = BN_CTX_new(); - size_t i; - char *k; - - (void)BN_zero(z); - (void)BN_zero(a); - (void)BN_set_word(base, 1 << 8); - BN_add(a, ck, z); - - for (i = 0; i < ((KEYSIZE - 64) / 2) / 8; i++) - BN_div(a, z, a, base, ctx); - - k = (char *)deskey; - for (i = 0; i < 8; i++) { - BN_div(a, z, a, base, ctx); - *k++ = (char)BN_get_word(z); - } - - BN_CTX_free(ctx); - BN_free(base); - BN_free(z); - BN_free(a); -} - -/* - * get common key from my secret key and his public key - */ -void -common_key(char *xsecret, char *xpublic, IdeaData *ideakey, DesData *deskey) -{ - BIGNUM *public = BN_new(); - BIGNUM *secret = BN_new(); - BIGNUM *common = BN_new(); - BIGNUM *modulus = BN_new(); - BN_CTX *ctx = BN_CTX_new(); - - (void)BN_hex2bn(&modulus, HEXMODULUS); - (void)BN_hex2bn(&public, xpublic); - (void)BN_hex2bn(&secret, xsecret); - (void)BN_zero(common); - - BN_mod_exp(common, public, secret, modulus, ctx); - extractdeskey(common, deskey); - extractideakey(common, ideakey); - des_set_odd_parity(deskey); - - BN_CTX_free(ctx); - BN_free(common); - BN_free(secret); - BN_free(public); - BN_free(modulus); -} - -/* - * Generate a seed - */ -static void -getseed(char *seed, size_t seedsize) -{ - size_t i; - - for (i = 0; i < seedsize; i++) - seed[i] = arc4random() & 0xff; -} - -/* - * Generate a random public/secret key pair - */ -void -genkeys(char *public, char *secret) -{ - size_t i; - -# define BASEBITS (8 * sizeof(short) - 1) -# define BASE (1 << BASEBITS) - - BIGNUM *pk = BN_new(); - BIGNUM *sk = BN_new(); - BIGNUM *tmp = BN_new(); - BIGNUM *base = BN_new(); - BIGNUM *root = BN_new(); - BIGNUM *modulus = BN_new(); - BN_CTX *ctx = BN_CTX_new(); - short r; - unsigned short seed[KEYSIZE/BASEBITS + 1]; - char *xkey; - - (void)BN_zero(pk); - (void)BN_zero(sk); - (void)BN_set_word(base, BASE); - (void)BN_set_word(root, PROOT); - (void)BN_hex2bn(&modulus, HEXMODULUS); - - getseed((char *)seed, sizeof(seed)); - for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) { - r = seed[i] % BASE; - (void)BN_set_word(tmp, r); - BN_mul(sk, tmp, sk, ctx); - BN_add(sk, tmp, sk); - } - - (void)BN_zero(tmp); - BN_div(tmp, sk, sk, modulus, ctx); - BN_mod_exp(pk, root, sk, modulus, ctx); - - xkey = BN_bn2hex(sk); - adjust(secret, xkey); - xkey = BN_bn2hex(pk); - adjust(public, xkey); - - BN_CTX_free(ctx); - BN_free(sk); - BN_free(base); - BN_free(pk); - BN_free(tmp); - BN_free(root); - BN_free(modulus); -} - -/* - * Adjust the input key so that it is 0-filled on the left - */ -static void -adjust(char *keyout, const char *keyin) -{ - const char *p; - char *s; - - for (p = keyin; *p; p++) - continue; - for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) - *s = *p; - while (s >= keyout) - *s-- = '0'; -} - -static const char hextab[] = "0123456789ABCDEF"; - -/* given a DES key, cbc encrypt and translate input to terminated hex */ -void -pk_encode(const char *in, char *out, DesData *key) -{ - char buf[256]; - DesData i; - des_key_schedule k; - size_t l, op, deslen; - - (void)memset(&i, 0, sizeof(i)); - (void)memset(buf, 0, sizeof(buf)); - deslen = ((strlen(in) + 7) / 8) * 8; - des_key_sched(key, k); - des_cbc_encrypt(in, buf, deslen, k, &i, DES_ENCRYPT); - for (l = 0, op = 0; l < deslen; l++) { - out[op++] = hextab[(buf[l] & 0xf0) >> 4]; - out[op++] = hextab[(buf[l] & 0x0f)]; - } - out[op] = '\0'; -} - -/* given a DES key, translate input from hex and decrypt */ -void -pk_decode(const char *in, char *out, DesData *key) -{ - char buf[256]; - DesData i; - des_key_schedule k; - int n1, n2, op; - size_t l; - size_t len = strlen(in) / 2; - - (void)memset(&i, 0, sizeof(i)); - (void)memset(buf, 0, sizeof(buf)); - - for (l = 0, op = 0; l < len; l++, op += 2) { - if (in[op] > '9') - n1 = in[op] - 'A' + 10; - else - n1 = in[op] - '0'; - if (in[op + 1] > '9') - n2 = in[op + 1] - 'A' + 10; - else - n2 = in[op + 1] - '0'; - buf[l] = (char)(n1 * 16 + n2); - } - des_key_sched(key, k); - des_cbc_encrypt(buf, out, len, k, &i, DES_DECRYPT); - out[len] = '\0'; -} diff --git a/lib/libtelnet/shlib_version b/lib/libtelnet/shlib_version deleted file mode 100644 index 4075bd016..000000000 --- a/lib/libtelnet/shlib_version +++ /dev/null @@ -1,5 +0,0 @@ -# $NetBSD: shlib_version,v 1.11 2009/01/11 03:07:50 christos Exp $ -# Remember to update distrib/sets/lists/base/shl.* when changing -# -major=7 -minor=0 diff --git a/lib/libtelnet/spx.c b/lib/libtelnet/spx.c deleted file mode 100644 index 054fc513c..000000000 --- a/lib/libtelnet/spx.c +++ /dev/null @@ -1,594 +0,0 @@ -/* $NetBSD: spx.c,v 1.7 2005/04/19 03:19:46 christos Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)spx.c 8.2 (Berkeley) 5/30/95"; -#else -__RCSID("$NetBSD: spx.c,v 1.7 2005/04/19 03:19:46 christos Exp $"); -#endif -#endif /* not lint */ - -#ifdef SPX -/* - * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION - * ALL RIGHTS RESERVED - * - * "Digital Equipment Corporation authorizes the reproduction, - * distribution and modification of this software subject to the following - * restrictions: - * - * 1. Any partial or whole copy of this software, or any modification - * thereof, must include this copyright notice in its entirety. - * - * 2. This software is supplied "as is" with no warranty of any kind, - * expressed or implied, for any purpose, including any warranty of fitness - * or merchantibility. DIGITAL assumes no responsibility for the use or - * reliability of this software, nor promises to provide any form of - * support for it on any basis. - * - * 3. Distribution of this software is authorized only if no profit or - * remuneration of any kind is received in exchange for such distribution. - * - * 4. This software produces public key authentication certificates - * bearing an expiration date established by DIGITAL and RSA Data - * Security, Inc. It may cease to generate certificates after the expiration - * date. Any modification of this software that changes or defeats - * the expiration date or its effect is unauthorized. - * - * 5. Software that will renew or extend the expiration date of - * authentication certificates produced by this software may be obtained - * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA - * 94065, (415)595-8782, or from DIGITAL" - * - */ - -#include -#include -#include -#include "gssapi_defs.h" -#include -#ifdef NO_STRING_H -#include -#else -#include -#endif - -#include -#include "encrypt.h" -#include "auth.h" -#include "misc.h" - -extern auth_debug_mode; - -static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0, - AUTHTYPE_SPX, }; -static unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION, - TELQUAL_NAME, }; - -#define SPX_AUTH 0 /* Authentication data follows */ -#define SPX_REJECT 1 /* Rejected (reason might follow) */ -#define SPX_ACCEPT 2 /* Accepted */ - -#ifdef ENCRYPTION -static Block session_key = { 0 }; -#endif /* ENCRYPTION */ -static Schedule sched; -static Block challenge = { 0 }; - - -/*******************************************************************/ - -gss_OID_set actual_mechs; -gss_OID actual_mech_type, output_name_type; -int major_status, status, msg_ctx = 0, new_status; -int req_flags = 0, ret_flags, lifetime_rec; -gss_cred_id_t gss_cred_handle; -gss_ctx_id_t actual_ctxhandle, context_handle; -gss_buffer_desc output_token, input_token, input_name_buffer; -gss_buffer_desc status_string; -gss_name_t desired_targname, src_name; -gss_channel_bindings input_chan_bindings; -char lhostname[GSS_C_MAX_PRINTABLE_NAME]; -char targ_printable[GSS_C_MAX_PRINTABLE_NAME]; -int to_addr=0, from_addr=0; -char *address; -gss_buffer_desc fullname_buffer; -gss_OID fullname_type; -gss_cred_id_t gss_delegated_cred_handle; - -/*******************************************************************/ - - - - static int -Data(ap, type, d, c) - Authenticator *ap; - int type; - void *d; - int c; -{ - unsigned char *p = str_data + 4; - unsigned char *cd = (unsigned char *)d; - - if (c == -1) - c = strlen((char *)cd); - - if (0) { - printf("%s:%d: [%d] (%d)", - str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", - str_data[3], - type, c); - printd(d, c); - printf("\r\n"); - } - *p++ = ap->type; - *p++ = ap->way; - *p++ = type; - while (c-- > 0) { - if ((*p++ = *cd++) == IAC) - *p++ = IAC; - } - *p++ = IAC; - *p++ = SE; - if (str_data[3] == TELQUAL_IS) - printsub('>', &str_data[2], p - (&str_data[2])); - return(telnet_net_write(str_data, p - str_data)); -} - - int -spx_init(ap, server) - Authenticator *ap; - int server; -{ - gss_cred_id_t tmp_cred_handle; - - if (server) { - str_data[3] = TELQUAL_REPLY; - gethostname(lhostname, sizeof(lhostname)); - strlcpy(targ_printable, "SERVICE:rcmd@", - sizeof(targ_printable)); - strlcat(targ_printable, lhostname, sizeof(targ_printable)); - input_name_buffer.length = strlen(targ_printable); - input_name_buffer.value = targ_printable; - major_status = gss_import_name(&status, - &input_name_buffer, - GSS_C_NULL_OID, - &desired_targname); - major_status = gss_acquire_cred(&status, - desired_targname, - 0, - GSS_C_NULL_OID_SET, - GSS_C_ACCEPT, - &tmp_cred_handle, - &actual_mechs, - &lifetime_rec); - if (major_status != GSS_S_COMPLETE) return(0); - } else { - str_data[3] = TELQUAL_IS; - } - return(1); -} - - int -spx_send(ap) - Authenticator *ap; -{ - Block enckey; - int r; - - gss_OID actual_mech_type, output_name_type; - int msg_ctx = 0, new_status, status; - int req_flags = 0, ret_flags, lifetime_rec, major_status; - gss_buffer_desc output_token, input_token, input_name_buffer; - gss_buffer_desc output_name_buffer, status_string; - gss_name_t desired_targname; - gss_channel_bindings input_chan_bindings; - char targ_printable[GSS_C_MAX_PRINTABLE_NAME]; - int from_addr=0, to_addr=0, myhostlen, j; - int deleg_flag=1, mutual_flag=0, replay_flag=0, seq_flag=0; - char *address; - - printf("[ Trying SPX ... ]\n"); - strlcpy(targ_printable, "SERVICE:rcmd@", sizeof(targ_printable)); - strlcat(targ_printable, RemoteHostName, sizeof(targ_printable)); - - input_name_buffer.length = strlen(targ_printable); - input_name_buffer.value = targ_printable; - - if (!UserNameRequested) { - return(0); - } - - major_status = gss_import_name(&status, - &input_name_buffer, - GSS_C_NULL_OID, - &desired_targname); - - - major_status = gss_display_name(&status, - desired_targname, - &output_name_buffer, - &output_name_type); - - printf("target is '%s'\n", output_name_buffer.value); fflush(stdout); - - major_status = gss_release_buffer(&status, &output_name_buffer); - - input_chan_bindings = (gss_channel_bindings) - malloc(sizeof(gss_channel_bindings_desc)); - - input_chan_bindings->initiator_addrtype = GSS_C_AF_INET; - input_chan_bindings->initiator_address.length = 4; - address = (char *) malloc(4); - input_chan_bindings->initiator_address.value = (char *) address; - address[0] = ((from_addr & 0xff000000) >> 24); - address[1] = ((from_addr & 0xff0000) >> 16); - address[2] = ((from_addr & 0xff00) >> 8); - address[3] = (from_addr & 0xff); - input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET; - input_chan_bindings->acceptor_address.length = 4; - address = (char *) malloc(4); - input_chan_bindings->acceptor_address.value = (char *) address; - address[0] = ((to_addr & 0xff000000) >> 24); - address[1] = ((to_addr & 0xff0000) >> 16); - address[2] = ((to_addr & 0xff00) >> 8); - address[3] = (to_addr & 0xff); - input_chan_bindings->application_data.length = 0; - - req_flags = 0; - if (deleg_flag) req_flags = req_flags | 1; - if (mutual_flag) req_flags = req_flags | 2; - if (replay_flag) req_flags = req_flags | 4; - if (seq_flag) req_flags = req_flags | 8; - - major_status = gss_init_sec_context(&status, /* minor status */ - GSS_C_NO_CREDENTIAL, /* cred handle */ - &actual_ctxhandle, /* ctx handle */ - desired_targname, /* target name */ - GSS_C_NULL_OID, /* mech type */ - req_flags, /* req flags */ - 0, /* time req */ - input_chan_bindings, /* chan binding */ - GSS_C_NO_BUFFER, /* input token */ - &actual_mech_type, /* actual mech */ - &output_token, /* output token */ - &ret_flags, /* ret flags */ - &lifetime_rec); /* time rec */ - - if ((major_status != GSS_S_COMPLETE) && - (major_status != GSS_S_CONTINUE_NEEDED)) { - gss_display_status(&new_status, - status, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &status_string); - printf("%s\n", status_string.value); - return(0); - } - - if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) { - return(0); - } - - if (!Data(ap, SPX_AUTH, (void *)output_token.value, output_token.length)) { - return(0); - } - - return(1); -} - - void -spx_is(ap, data, cnt) - Authenticator *ap; - unsigned char *data; - int cnt; -{ - Session_Key skey; - Block datablock; - int r; - - if (cnt-- < 1) - return; - switch (*data++) { - case SPX_AUTH: - input_token.length = cnt; - input_token.value = (char *) data; - - gethostname(lhostname, sizeof(lhostname)); - - strlcpy(targ_printable, "SERVICE:rcmd@", - sizeof(targ_printable)); - strlcat(targ_printable, lhostname, sizeof(targ_printable)); - - input_name_buffer.length = strlen(targ_printable); - input_name_buffer.value = targ_printable; - - major_status = gss_import_name(&status, - &input_name_buffer, - GSS_C_NULL_OID, - &desired_targname); - - major_status = gss_acquire_cred(&status, - desired_targname, - 0, - GSS_C_NULL_OID_SET, - GSS_C_ACCEPT, - &gss_cred_handle, - &actual_mechs, - &lifetime_rec); - - major_status = gss_release_name(&status, desired_targname); - - input_chan_bindings = (gss_channel_bindings) - malloc(sizeof(gss_channel_bindings_desc)); - - input_chan_bindings->initiator_addrtype = GSS_C_AF_INET; - input_chan_bindings->initiator_address.length = 4; - address = (char *) malloc(4); - input_chan_bindings->initiator_address.value = (char *) address; - address[0] = ((from_addr & 0xff000000) >> 24); - address[1] = ((from_addr & 0xff0000) >> 16); - address[2] = ((from_addr & 0xff00) >> 8); - address[3] = (from_addr & 0xff); - input_chan_bindings->acceptor_addrtype = GSS_C_AF_INET; - input_chan_bindings->acceptor_address.length = 4; - address = (char *) malloc(4); - input_chan_bindings->acceptor_address.value = (char *) address; - address[0] = ((to_addr & 0xff000000) >> 24); - address[1] = ((to_addr & 0xff0000) >> 16); - address[2] = ((to_addr & 0xff00) >> 8); - address[3] = (to_addr & 0xff); - input_chan_bindings->application_data.length = 0; - - major_status = gss_accept_sec_context(&status, - &context_handle, - gss_cred_handle, - &input_token, - input_chan_bindings, - &src_name, - &actual_mech_type, - &output_token, - &ret_flags, - &lifetime_rec, - &gss_delegated_cred_handle); - - - if (major_status != GSS_S_COMPLETE) { - - major_status = gss_display_name(&status, - src_name, - &fullname_buffer, - &fullname_type); - Data(ap, SPX_REJECT, (void *)"auth failed", -1); - auth_finished(ap, AUTH_REJECT); - return; - } - - major_status = gss_display_name(&status, - src_name, - &fullname_buffer, - &fullname_type); - - - Data(ap, SPX_ACCEPT, (void *)output_token.value, output_token.length); - auth_finished(ap, AUTH_USER); - break; - - default: - Data(ap, SPX_REJECT, 0, 0); - break; - } -} - - - void -spx_reply(ap, data, cnt) - Authenticator *ap; - unsigned char *data; - int cnt; -{ - Session_Key skey; - - if (cnt-- < 1) - return; - switch (*data++) { - case SPX_REJECT: - if (cnt > 0) { - printf("[ SPX refuses authentication because %.*s ]\r\n", - cnt, data); - } else - printf("[ SPX refuses authentication ]\r\n"); - auth_send_retry(); - return; - case SPX_ACCEPT: - printf("[ SPX accepts you ]\n"); - if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) { - /* - * Send over the encrypted challenge. - */ - input_token.value = (char *) data; - input_token.length = cnt; - - major_status = gss_init_sec_context(&status, /* minor stat */ - GSS_C_NO_CREDENTIAL, /* cred handle */ - &actual_ctxhandle, /* ctx handle */ - desired_targname, /* target name */ - GSS_C_NULL_OID, /* mech type */ - req_flags, /* req flags */ - 0, /* time req */ - input_chan_bindings, /* chan binding */ - &input_token, /* input token */ - &actual_mech_type, /* actual mech */ - &output_token, /* output token */ - &ret_flags, /* ret flags */ - &lifetime_rec); /* time rec */ - - if (major_status != GSS_S_COMPLETE) { - gss_display_status(&new_status, - status, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &status_string); - printf("[ SPX mutual response fails ... '%s' ]\r\n", - status_string.value); - auth_send_retry(); - return; - } - } - auth_finished(ap, AUTH_USER); - return; - - default: - return; - } -} - - int -spx_status(ap, name, l, level) - Authenticator *ap; - char *name; - size_t l; - int level; -{ - - gss_buffer_desc fullname_buffer, acl_file_buffer; - gss_OID fullname_type; - char acl_file[160], fullname[160]; - int major_status, status = 0; - struct passwd pws, *pwd; - char pwbuf[1024]; - - /* - * hard code fullname to - * "SPX:/C=US/O=Digital/OU=LKG/OU=Sphinx/OU=Users/CN=Kannan Alagappan" - * and acl_file to "~kannan/.sphinx" - */ - - if (getpwnam_r(UserNameRequested, &pws, pwbuf, sizeof(pwbuf), &pwd) - != 0 || pwd == NULL) { - return(AUTH_USER); /* not authenticated */ - } - - strlcpy(acl_file, pwd->pw_dir, sizeof(acl_file)); - strlcat(acl_file, "/.sphinx", sizeof(acl_file)); - acl_file_buffer.value = acl_file; - acl_file_buffer.length = strlen(acl_file); - - major_status = gss_display_name(&status, - src_name, - &fullname_buffer, - &fullname_type); - - if (level < AUTH_USER) - return(level); - - major_status = gss__check_acl(&status, &fullname_buffer, - &acl_file_buffer); - - if (major_status == GSS_S_COMPLETE) { - strlcpy(name, UserNameRequested, l); - return(AUTH_VALID); - } else { - return(AUTH_USER); - } - -} - -#define BUMP(buf, len) while (*(buf)) {++(buf), --(len);} -#define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);} - - void -spx_printsub(data, cnt, buf, buflen) - unsigned char *data, *buf; - int cnt, buflen; -{ - char lbuf[32]; - register int i; - - buf[buflen-1] = '\0'; /* make sure its NULL terminated */ - buflen -= 1; - - switch(data[3]) { - case SPX_REJECT: /* Rejected (reason might follow) */ - strncpy((char *)buf, " REJECT ", buflen); - goto common; - - case SPX_ACCEPT: /* Accepted (name might follow) */ - strncpy((char *)buf, " ACCEPT ", buflen); - common: - BUMP(buf, buflen); - if (cnt <= 4) - break; - ADDC(buf, buflen, '"'); - for (i = 4; i < cnt; i++) - ADDC(buf, buflen, data[i]); - ADDC(buf, buflen, '"'); - ADDC(buf, buflen, '\0'); - break; - - case SPX_AUTH: /* Authentication data follows */ - strncpy((char *)buf, " AUTH", buflen); - goto common2; - - default: - snprintf(lbuf, sizeof(lbuf), " %d (unknown)", data[3]); - strncpy((char *)buf, lbuf, buflen); - common2: - BUMP(buf, buflen); - for (i = 4; i < cnt; i++) { - snprintf(lbuf, sizeof(lbuf), " %d", data[i]); - strncpy((char *)buf, lbuf, buflen); - BUMP(buf, buflen); - } - break; - } -} - -#endif - -#ifdef notdef - -prkey(msg, key) - char *msg; - unsigned char *key; -{ - register int i; - printf("%s:", msg); - for (i = 0; i < 8; i++) - printf(" %3d", key[i]); - printf("\r\n"); -} -#endif