mount_unionfs.c revision 147242
14Srgrimes/*
2509Srgrimes * Copyright (c) 1992, 1993, 1994
316028Speter *	The Regents of the University of California.  All rights reserved.
44Srgrimes *
5509Srgrimes * This code is derived from software donated to Berkeley by
6509Srgrimes * Jan-Simon Pendry.
74Srgrimes *
84Srgrimes * Redistribution and use in source and binary forms, with or without
94Srgrimes * modification, are permitted provided that the following conditions
104Srgrimes * are met:
114Srgrimes * 1. Redistributions of source code must retain the above copyright
124Srgrimes *    notice, this list of conditions and the following disclaimer.
134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
144Srgrimes *    notice, this list of conditions and the following disclaimer in the
154Srgrimes *    documentation and/or other materials provided with the distribution.
164Srgrimes * 4. Neither the name of the University nor the names of its contributors
178876Srgrimes *    may be used to endorse or promote products derived from this software
183698Swollman *    without specific prior written permission.
195908Sbde *
204Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
212056Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
222056Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
232056Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
244Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
252056Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
262056Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2810079Sbde * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2912880Sbde * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3012880Sbde * SUCH DAMAGE.
31798Swollman */
323863Sbde
3312880Sbde#ifndef lint
34798Swollmanstatic const char copyright[] =
35798Swollman"@(#) Copyright (c) 1992, 1993, 1994\n\
36798Swollman	The Regents of the University of California.  All rights reserved.\n";
37798Swollman#endif /* not lint */
384836Sdg
396733Sbde#ifndef lint
407627Snate#if 0
417627Snatestatic char sccsid[] = "@(#)mount_union.c	8.5 (Berkeley) 3/27/94";
427627Snate#else
437627Snatestatic const char rcsid[] =
447627Snate  "$FreeBSD: head/sbin/mount_unionfs/mount_unionfs.c 147242 2005-06-10 09:51:43Z delphij $";
457627Snate#endif
467627Snate#endif /* not lint */
4712400Sdg
48712Swollman#include <sys/param.h>
49974Sdg#include <sys/mount.h>
504Srgrimes#include <sys/uio.h>
514Srgrimes
524Srgrimes#include <err.h>
532408Sbde#include <stdio.h>
5416028Speter#include <stdlib.h>
554Srgrimes#include <string.h>
564Srgrimes#include <sysexits.h>
5716028Speter#include <unistd.h>
583863Sbde
592408Sbde#include "mntopts.h"
602408Sbde
612408Sbdestatic struct mntopt mopts[] = {
628876Srgrimes	MOPT_STDOPTS,
6313031Sbde	MOPT_END
645908Sbde};
6513031Sbde
665908Sbdestatic int	subdir(const char *, const char *);
675908Sbdestatic void	usage (void) __dead2;
685908Sbde
695908Sbdeint
706018Sphkmain(argc, argv)
715908Sbde	int argc;
724Srgrimes	char *argv[];
735327Sgibbs{
745327Sgibbs	struct iovec iov[8];
754Srgrimes	int ch, mntflags;
764Srgrimes	char source[MAXPATHLEN];
774Srgrimes	char target[MAXPATHLEN];
784Srgrimes	int iovcnt;
7911918Sdg
8011918Sdg	iovcnt = 6;
814Srgrimes	mntflags = 0;
824Srgrimes	while ((ch = getopt(argc, argv, "bo:r")) != -1)
836802Sgibbs		switch (ch) {
846802Sgibbs		case 'b':
854Srgrimes			iov[6].iov_base = "below";
8613031Sbde			iov[6].iov_len = strlen(iov[6].iov_base) + 1;
879647Sbde			iov[7].iov_base = NULL;
889647Sbde			iov[7].iov_len = 0;
894Srgrimes			iovcnt = 8;
90715Swollman			break;
913863Sbde		case 'o':
92715Swollman			getmntopts(optarg, mopts, &mntflags, 0);
93715Swollman			break;
94715Swollman		case 'r':
954Srgrimes			iov[6].iov_base = "replace";
965908Sbde			iov[6].iov_len = strlen(iov[6].iov_base) + 1;
975908Sbde			iov[7].iov_base = NULL;
985908Sbde			iov[7].iov_len = 0;
995908Sbde			iovcnt = 8;
1004Srgrimes			break;
1014Srgrimes		case '?':
1024Srgrimes		default:
1034Srgrimes			usage();
1042464Sbde			/* NOTREACHED */
1052408Sbde		}
1064Srgrimes	argc -= optind;
1072408Sbde	argv += optind;
1082408Sbde
1092408Sbde	if (argc != 2)
1102408Sbde		usage();
111757Sdg
1124Srgrimes	/* resolve both target and source with realpath(3) */
1134Srgrimes	(void)checkpath(argv[0], target);
1144Srgrimes	(void)checkpath(argv[1], source);
11513259Swollman
11613259Swollman	if (subdir(target, source) || subdir(source, target))
1174Srgrimes		errx(EX_USAGE, "%s (%s) and %s (%s) are not distinct paths",
1184Srgrimes		    argv[0], target, argv[1], source);
1194Srgrimes
1204Srgrimes	iov[0].iov_base = "fstype";
1212408Sbde	iov[0].iov_len = strlen(iov[0].iov_base) + 1;
1222408Sbde	iov[1].iov_base = "unionfs";
1232408Sbde	iov[1].iov_len = strlen(iov[1].iov_base) + 1;
124649Snate	iov[2].iov_base = "fspath";
1253863Sbde	iov[2].iov_len = strlen(iov[2].iov_base) + 1;
1264Srgrimes	iov[3].iov_base = source;
1278876Srgrimes	iov[3].iov_len = strlen(source) + 1;
128715Swollman	iov[4].iov_base = "target";
1293863Sbde	iov[4].iov_len = strlen(iov[4].iov_base) + 1;
1304508Sbde	iov[5].iov_base = target;
1314Srgrimes	iov[5].iov_len = strlen(target) + 1;
1323863Sbde	if (nmount(iov, iovcnt, mntflags))
1333863Sbde		err(EX_OSERR, "%s", target);
1343863Sbde	exit(0);
1352408Sbde}
1365327Sgibbs
13714924Speterint
13814924Spetersubdir(p, dir)
13914924Speter	const char *p;
14014924Speter	const char *dir;
14114924Speter{
14214331Speter	int l;
14315679Swosch
1444Srgrimes	l = strlen(dir);
1454Srgrimes	if (l <= 1)
1468457Swollman		return (1);
1474Srgrimes
1488457Swollman	if ((strncmp(p, dir, l) == 0) && (p[l] == '/' || p[l] == '\0'))
1494Srgrimes		return (1);
1504Srgrimes
1514Srgrimes	return (0);
1524Srgrimes}
1534Srgrimes
1544Srgrimesvoid
1554Srgrimesusage()
15615558Sjoerg{
15715558Sjoerg	(void)fprintf(stderr,
15815558Sjoerg		"usage: mount_unionfs [-br] [-o options] directory uniondir\n");
15915558Sjoerg	exit(EX_USAGE);
16015558Sjoerg}
1612823Sjkh