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