166067Spendry /*
266067Spendry  * Copyright (c) 1992, 1993, 1994
366067Spendry  *	The Regents of the University of California.  All rights reserved.
466067Spendry  *
566067Spendry  * This code is derived from software donated to Berkeley by
666067Spendry  * Jan-Simon Pendry.
766067Spendry  *
866067Spendry  * %sccs.include.redist.c%
966067Spendry  */
1066067Spendry 
1166479Sbostic #ifndef lint
1266479Sbostic char copyright[] =
1366479Sbostic "@(#) Copyright (c) 1992, 1993, 1994\n\
1466479Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1566479Sbostic #endif /* not lint */
1666479Sbostic 
1766479Sbostic #ifndef lint
18*68905Smckusick static char sccsid[] = "@(#)mount_union.c	8.6 (Berkeley) 04/26/95";
1966479Sbostic #endif /* not lint */
2066479Sbostic 
2166067Spendry #include <sys/param.h>
2266067Spendry #include <sys/mount.h>
2366479Sbostic 
2466067Spendry #include <miscfs/union/union.h>
2566067Spendry 
2666479Sbostic #include <err.h>
2766067Spendry #include <stdio.h>
2866067Spendry #include <stdlib.h>
2966067Spendry #include <string.h>
3066479Sbostic #include <unistd.h>
3166067Spendry 
3266479Sbostic #include "mntopts.h"
3366067Spendry 
3466479Sbostic struct mntopt mopts[] = {
3566479Sbostic 	MOPT_STDOPTS,
3666479Sbostic 	{ NULL }
3766479Sbostic };
3866479Sbostic 
3966479Sbostic int	subdir __P((const char *, const char *));
4066479Sbostic void	usage __P((void));
4166479Sbostic 
4266067Spendry int
main(argc,argv)4366067Spendry main(argc, argv)
4466067Spendry 	int argc;
4566067Spendry 	char *argv[];
4666067Spendry {
4766067Spendry 	struct union_args args;
4866067Spendry 	int ch, mntflags;
4966136Spendry 	char target[MAXPATHLEN];
5066067Spendry 
5166067Spendry 	mntflags = 0;
5266067Spendry 	args.mntflags = UNMNT_ABOVE;
5366482Sbostic 	while ((ch = getopt(argc, argv, "bo:r")) != EOF)
5466479Sbostic 		switch (ch) {
5566067Spendry 		case 'b':
5666479Sbostic 			args.mntflags &= ~UNMNT_OPMASK;
5766479Sbostic 			args.mntflags |= UNMNT_BELOW;
5866067Spendry 			break;
5966479Sbostic 		case 'o':
60*68905Smckusick 			getmntopts(optarg, mopts, &mntflags, 0);
6166479Sbostic 			break;
6266067Spendry 		case 'r':
6366479Sbostic 			args.mntflags &= ~UNMNT_OPMASK;
6466479Sbostic 			args.mntflags |= UNMNT_REPLACE;
6566067Spendry 			break;
6666067Spendry 		case '?':
6766067Spendry 		default:
6866479Sbostic 			usage();
6966482Sbostic 			/* NOTREACHED */
7066067Spendry 		}
7166067Spendry 	argc -= optind;
7266067Spendry 	argv += optind;
7366067Spendry 
7466067Spendry 	if (argc != 2)
7566067Spendry 		usage();
7666067Spendry 
7766479Sbostic 	if (realpath(argv[0], target) == 0)
7866479Sbostic 		err(1, "%s", target);
7966067Spendry 
8066479Sbostic 	if (subdir(target, argv[1]) || subdir(argv[1], target))
8166479Sbostic 		errx(1, "%s (%s) and %s are not distinct paths",
8266479Sbostic 		    argv[0], target, argv[1]);
8366136Spendry 
8466136Spendry 	args.target = target;
8566136Spendry 
86*68905Smckusick 	if (mount("union", argv[1], mntflags, &args))
8766479Sbostic 		err(1, NULL);
8866067Spendry 	exit(0);
8966067Spendry }
9066067Spendry 
9166479Sbostic int
subdir(p,dir)9266136Spendry subdir(p, dir)
9366222Spendry 	const char *p;
9466222Spendry 	const char *dir;
9566136Spendry {
9666136Spendry 	int l;
9766136Spendry 
9866136Spendry 	l = strlen(dir);
9966136Spendry 	if (l <= 1)
10066136Spendry 		return (1);
10166136Spendry 
10266222Spendry 	if ((strncmp(p, dir, l) == 0) && (p[l] == '/' || p[l] == '\0'))
10366136Spendry 		return (1);
10466136Spendry 
10566136Spendry 	return (0);
10666136Spendry }
10766136Spendry 
10866067Spendry void
usage()10966067Spendry usage()
11066067Spendry {
11166067Spendry 	(void)fprintf(stderr,
11266482Sbostic 		"usage: mount_union [-br] [-o options] target_fs mount_point\n");
11366067Spendry 	exit(1);
11466067Spendry }
115