diff options
Diffstat (limited to 'lib/libautofs/libautofs.c')
-rw-r--r-- | lib/libautofs/libautofs.c | 479 |
1 files changed, 0 insertions, 479 deletions
diff --git a/lib/libautofs/libautofs.c b/lib/libautofs/libautofs.c deleted file mode 100644 index 459b32d..0000000 --- a/lib/libautofs/libautofs.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (c) 2004 Alfred Perlstein <alfred@FreeBSD.org> - * 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. - * - * $FreeBSD$ - * $Id: libautofs.c,v 1.5 2004/09/08 08:44:12 bright Exp $ - */ -#include <err.h> -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/mount.h> -#include <sys/poll.h> -#include <sys/stat.h> -#include <sys/sysctl.h> - -#ifdef AUTOFSSTANDALONE -#include "../autofs/autofs.h" -#else -#include <fs/autofs/autofs.h> -#endif - -#include "libautofs.h" - -struct auto_handle { - char ah_mp[MNAMELEN]; - fsid_t ah_fsid; - int ah_fd; -}; - -static int autofs_sysctl(int, fsid_t *, void *, size_t *, void *, size_t); -static void safe_free(void *ptr); -static int getmntlst(struct statfs **sfsp, int *cntp); - -static void -safe_free(void *ptr) -{ - int saved_errno; - - saved_errno = errno; - free(ptr); - errno = saved_errno; -} - -int -getmntlst(struct statfs **sfsp, int *cntp) -{ - int cnt; - long bufsize; - - *sfsp = NULL; - cnt = getfsstat(NULL, 0, MNT_NOWAIT); - bufsize = cnt * sizeof(**sfsp); - /*fprintf(stderr, "getmntlst bufsize %ld, cnt %d\n", bufsize, cnt);*/ - *sfsp = malloc(bufsize); - if (sfsp == NULL) - goto err; - cnt = getfsstat(*sfsp, bufsize, MNT_NOWAIT); - if (cnt == -1) - goto err; - *cntp = cnt; - /*fprintf(stderr, "getmntlst ok, cnt %d\n", cnt);*/ - return (0); -err: - safe_free(sfsp); - *sfsp = NULL; - /*fprintf(stderr, "getmntlst bad\n");*/ - return (-1); -} - -/* get a handle based on a path. */ -int -autoh_get(const char *path, autoh_t *ahp) -{ - struct statfs *sfsp, *sp; - int cnt, fd, i; - autoh_t ret; - - ret = NULL; - /* - * We use getfsstat to prevent avoid the lookups on the mountpoints - * that statfs(2) would do. - */ - if (getmntlst(&sfsp, &cnt)) - goto err; - for (i = 0; i < cnt; i++) { - if (strcmp(sfsp[i].f_mntonname, path) == 0) - break; - } - if (i == cnt) { - /*fprintf(stderr, "autoh_get bad %d %d\n", i, cnt);*/ - errno = ENOENT; - goto err; - } - sp = &sfsp[i]; - if (strcmp(sp->f_fstypename, "autofs")) { - errno = ENOTTY; - goto err; - } - fd = open(sp->f_mntonname, O_RDONLY); - if (fd == -1) - goto err; - ret = malloc(sizeof(*ret)); - if (ret == NULL) - goto err; - - ret->ah_fsid = sp->f_fsid; - ret->ah_fd = fd; - strlcpy(ret->ah_mp, sp->f_mntonname, sizeof(ret->ah_mp)); - safe_free(sfsp); - *ahp = ret; - return (0); -err: - safe_free(ret); - safe_free(sfsp); - return (-1); -} - -/* release. */ -void -autoh_free(autoh_t ah) -{ - int saved_errno; - - saved_errno = errno; - close(ah->ah_fd); - free(ah); - errno = saved_errno; -} - -/* - * Get an array of pointers to all the currently mounted autofs - * instances. - */ -int -autoh_getall(autoh_t **arrayp, int *cntp) -{ - struct statfs *sfsp; - int cnt, i, pos; - autoh_t *array; - - array = NULL; - /* - * We use getfsstat to prevent avoid the lookups on the mountpoints - * that statfs(2) would do. - */ - if (getmntlst(&sfsp, &cnt)) - goto err; - array = *arrayp = calloc(cnt + 1, sizeof(**arrayp)); - if (array == NULL) - goto err; - for (i = 0, pos = 0; i < cnt; i++) { - if (autoh_get(sfsp[i].f_mntonname, &array[pos]) == -1) { - /* not an autofs entry, that's ok, otherwise bail */ - if (errno == ENOTTY) - continue; - goto err; - } - pos++; - } - if (pos == 0) { - errno = ENOENT; - goto err; - } - *arrayp = array; - *cntp = pos; - safe_free(sfsp); - return (0); -err: - safe_free(sfsp); - if (array) - autoh_freeall(array); - return (-1); -} - -/* release. */ -void -autoh_freeall(autoh_t *ah) -{ - autoh_t *ahp; - - ahp = ah; - - while (*ahp != NULL) { - autoh_free(*ahp); - ahp++; - } - safe_free(ah); -} - -/* return fd to select on. */ -int -autoh_fd(autoh_t ah) -{ - - return (ah->ah_fd); -} - -const char * -autoh_mp(autoh_t ah) -{ - - return (ah->ah_mp); -} - -static int do_autoreq_get(autoh_t ah, autoreq_t *reqp, int *cntp); - -/* get an array of pending requests */ -int -autoreq_get(autoh_t ah, autoreq_t **reqpp, int *cntp) -{ - int cnt, i; - autoreq_t req, *reqp; - - if (do_autoreq_get(ah, &req, &cnt)) - return (-1); - - reqp = calloc(cnt + 1, sizeof(*reqp)); - if (reqp == NULL) { - safe_free(req); - return (-1); - } - for (i = 0; i < cnt; i++) - reqp[i] = &req[i]; - *reqpp = reqp; - *cntp = cnt; - return (0); -} - -int -do_autoreq_get(autoh_t ah, autoreq_t *reqp, int *cntp) -{ - size_t olen; - struct autofs_userreq *reqs; - int cnt, error; - int vers; - - vers = AUTOFS_PROTOVERS; - - error = 0; - reqs = NULL; - olen = 0; - cnt = 0; - error = autofs_sysctl(AUTOFS_CTL_GETREQS, &ah->ah_fsid, NULL, &olen, - &vers, sizeof(vers)); - if (error == -1) - goto out; - if (olen == 0) - goto out; - - reqs = malloc(olen); - if (reqs == NULL) - goto out; - error = autofs_sysctl(AUTOFS_CTL_GETREQS, &ah->ah_fsid, reqs, &olen, - &vers, sizeof(vers)); - if (error == -1) - goto out; -out: - if (error) { - safe_free(reqs); - return (-1); - } - cnt = olen / sizeof(*reqs); - *cntp = cnt; - *reqp = reqs; - return (0); -} - -/* free an array of requests */ -void -autoreq_free(autoh_t ah __unused, autoreq_t *req) -{ - - free(*req); - free(req); -} - -/* serve a request */ -int -autoreq_serv(autoh_t ah, autoreq_t req) -{ - int error; - - error = autofs_sysctl(AUTOFS_CTL_SERVREQ, &ah->ah_fsid, NULL, NULL, - req, sizeof(*req)); - return (error); -} - -enum autoreq_op -autoreq_getop(autoreq_t req) -{ - - switch (req->au_op) { - case AREQ_LOOKUP: - return (AUTOREQ_OP_LOOKUP); - case AREQ_STAT: - return (AUTOREQ_OP_STAT); - case AREQ_READDIR: - return (AUTOREQ_OP_READDIR); - default: - return (AUTOREQ_OP_UNKNOWN); - } -} - -/* get a request's file name. */ -const char * -autoreq_getpath(autoreq_t req) -{ - - return (req->au_name); -} - -/* get a request's inode. a indirect mount may return AUTO_INODE_NONE. */ -autoino_t -autoreq_getino(autoreq_t req) -{ - - return (req->au_ino); -} - -void -autoreq_setino(autoreq_t req, autoino_t ino) -{ - - req->au_ino = ino; -} - -/* get a request's directory inode. */ -autoino_t -autoreq_getdirino(autoreq_t req) -{ - - return (req->au_dino); -} - -void -autoreq_seterrno(autoreq_t req, int error) -{ - - req->au_errno = error; -} - -void -autoreq_setaux(autoreq_t req, void *auxdata, size_t auxlen) -{ - - req->au_auxdata = auxdata; - req->au_auxlen = auxlen; -} - -void -autoreq_getaux(autoreq_t req, void **auxdatap, size_t *auxlenp) -{ - - *auxdatap = req->au_auxdata; - *auxlenp = req->au_auxlen; -} - -void -autoreq_seteof(autoreq_t req, int eof) -{ - - req->au_eofflag = eof; -} - -void -autoreq_getoffset(autoreq_t req, off_t *offp) -{ - - *offp = req->au_offset - AUTOFS_USEROFF; -} - -void -autoreq_getxid(autoreq_t req, int *xid) -{ - - *xid = req->au_xid; -} - -/* toggle by path. args = handle, AUTO_?, pid (-1 to disable), path. */ -int -autoh_togglepath(autoh_t ah, int op, pid_t pid, const char *path) -{ - int fd, ret; - - fd = open(path, O_RDONLY); - if (fd == -1) - return (-1); - ret = autoh_togglefd(ah, op, pid, fd); - close(fd); - return (ret); -} - -/* toggle by fd. args = handle, AUTO_?, pid (-1 to disable), fd. */ -int -autoh_togglefd(autoh_t ah, int op, pid_t pid, int fd) -{ - struct stat sb; - struct autofs_mounterreq mr; - int error, realop; - - switch (op) { - case AUTO_DIRECT: - realop = AUTOFS_CTL_TRIGGER; - break; - case AUTO_INDIRECT: - realop = AUTOFS_CTL_SUBTRIGGER; - break; - case AUTO_MOUNTER: - realop = AUTOFS_CTL_MOUNTER; - break; - case AUTO_BROWSE: - realop = AUTOFS_CTL_BROWSE; - break; - default: - errno = ENOTTY; - return (-1); - } - - if (fstat(fd, &sb)) - return (-1); - bzero(&mr, sizeof(mr)); - mr.amu_ino = sb.st_ino; - mr.amu_pid = pid; - error = autofs_sysctl(realop, &ah->ah_fsid, NULL, NULL, - &mr, sizeof(mr)); - return (error); -} - -int -autofs_sysctl(op, fsid, oldp, oldlenp, newp, newlen) - int op; - fsid_t *fsid; - void *oldp; - size_t *oldlenp; - void *newp; - size_t newlen; -{ - struct vfsidctl vc; - - bzero(&vc, sizeof(vc)); - vc.vc_op = op; - strcpy(vc.vc_fstypename, "*"); - vc.vc_vers = VFS_CTL_VERS1; - vc.vc_fsid = *fsid; - vc.vc_ptr = newp; - vc.vc_len = newlen; - return (sysctlbyname("vfs.autofs.ctl", oldp, oldlenp, &vc, sizeof(vc))); -} - |