1168404Spjd/*- 2168404Spjd * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3168404Spjd * All rights reserved. 4168404Spjd * 5168404Spjd * Redistribution and use in source and binary forms, with or without 6168404Spjd * modification, are permitted provided that the following conditions 7168404Spjd * are met: 8168404Spjd * 1. Redistributions of source code must retain the above copyright 9168404Spjd * notice, this list of conditions and the following disclaimer. 10168404Spjd * 2. Redistributions in binary form must reproduce the above copyright 11168404Spjd * notice, this list of conditions and the following disclaimer in the 12168404Spjd * documentation and/or other materials provided with the distribution. 13168404Spjd * 14168404Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15168404Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16168404Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17168404Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18168404Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19168404Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20168404Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21168404Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22168404Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23168404Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24168404Spjd * SUCH DAMAGE. 25168404Spjd */ 26168404Spjd 27168404Spjd/* 28168404Spjd * This file implements Solaris compatible zmount() function. 29168404Spjd */ 30168404Spjd 31168404Spjd#include <sys/cdefs.h> 32168404Spjd__FBSDID("$FreeBSD: stable/10/cddl/compat/opensolaris/misc/zmount.c 326327 2017-11-28 17:30:25Z asomers $"); 33168404Spjd 34168404Spjd#include <sys/param.h> 35168404Spjd#include <sys/mount.h> 36168404Spjd#include <sys/uio.h> 37168404Spjd#include <sys/mntent.h> 38185029Spjd#include <assert.h> 39168404Spjd#include <stdio.h> 40168404Spjd#include <stdlib.h> 41185029Spjd#include <string.h> 42219089Spjd#include <mnttab.h> 43168404Spjd 44168404Spjdstatic void 45168404Spjdbuild_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, 46168404Spjd size_t len) 47168404Spjd{ 48168404Spjd int i; 49168404Spjd 50168404Spjd if (*iovlen < 0) 51168404Spjd return; 52168404Spjd i = *iovlen; 53168404Spjd *iov = realloc(*iov, sizeof(**iov) * (i + 2)); 54168404Spjd if (*iov == NULL) { 55168404Spjd *iovlen = -1; 56168404Spjd return; 57168404Spjd } 58168404Spjd (*iov)[i].iov_base = strdup(name); 59168404Spjd (*iov)[i].iov_len = strlen(name) + 1; 60168404Spjd i++; 61168404Spjd (*iov)[i].iov_base = val; 62168404Spjd if (len == (size_t)-1) { 63168404Spjd if (val != NULL) 64168404Spjd len = strlen(val) + 1; 65168404Spjd else 66168404Spjd len = 0; 67168404Spjd } 68168404Spjd (*iov)[i].iov_len = (int)len; 69168404Spjd *iovlen = ++i; 70168404Spjd} 71168404Spjd 72168404Spjdint 73168404Spjdzmount(const char *spec, const char *dir, int mflag, char *fstype, 74168404Spjd char *dataptr, int datalen, char *optptr, int optlen) 75168404Spjd{ 76168404Spjd struct iovec *iov; 77326327Sasomers char *optstr, *os, *p, *tofree; 78168404Spjd int iovlen, rv; 79168404Spjd 80168404Spjd assert(spec != NULL); 81168404Spjd assert(dir != NULL); 82219089Spjd assert(mflag == 0 || mflag == MS_RDONLY); 83168404Spjd assert(fstype != NULL); 84168404Spjd assert(strcmp(fstype, MNTTYPE_ZFS) == 0); 85168404Spjd assert(dataptr == NULL); 86168404Spjd assert(datalen == 0); 87168404Spjd assert(optptr != NULL); 88168404Spjd assert(optlen > 0); 89168404Spjd 90326327Sasomers tofree = optstr = strdup(optptr); 91185029Spjd assert(optstr != NULL); 92168404Spjd 93168404Spjd iov = NULL; 94168404Spjd iovlen = 0; 95219089Spjd if (mflag & MS_RDONLY) 96219089Spjd build_iovec(&iov, &iovlen, "ro", NULL, 0); 97168404Spjd build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1); 98168404Spjd build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir), 99168404Spjd (size_t)-1); 100168404Spjd build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1); 101326327Sasomers while ((p = strsep(&optstr, ",/")) != NULL) 102326327Sasomers build_iovec(&iov, &iovlen, p, NULL, (size_t)-1); 103168404Spjd rv = nmount(iov, iovlen, 0); 104326327Sasomers free(tofree); 105168404Spjd return (rv); 106168404Spjd} 107