1 /* 2 * Copyright (c) 1992, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software donated to Berkeley by 6 * Jan-Simon Pendry. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1992, 1993, 1994\n\ 14 The Regents of the University of California. All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)mount_union.c 8.6 (Berkeley) 04/26/95"; 19 #endif /* not lint */ 20 21 #include <sys/param.h> 22 #include <sys/mount.h> 23 24 #include <miscfs/union/union.h> 25 26 #include <err.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 32 #include "mntopts.h" 33 34 struct mntopt mopts[] = { 35 MOPT_STDOPTS, 36 { NULL } 37 }; 38 39 int subdir __P((const char *, const char *)); 40 void usage __P((void)); 41 42 int 43 main(argc, argv) 44 int argc; 45 char *argv[]; 46 { 47 struct union_args args; 48 int ch, mntflags; 49 char target[MAXPATHLEN]; 50 51 mntflags = 0; 52 args.mntflags = UNMNT_ABOVE; 53 while ((ch = getopt(argc, argv, "bo:r")) != EOF) 54 switch (ch) { 55 case 'b': 56 args.mntflags &= ~UNMNT_OPMASK; 57 args.mntflags |= UNMNT_BELOW; 58 break; 59 case 'o': 60 getmntopts(optarg, mopts, &mntflags, 0); 61 break; 62 case 'r': 63 args.mntflags &= ~UNMNT_OPMASK; 64 args.mntflags |= UNMNT_REPLACE; 65 break; 66 case '?': 67 default: 68 usage(); 69 /* NOTREACHED */ 70 } 71 argc -= optind; 72 argv += optind; 73 74 if (argc != 2) 75 usage(); 76 77 if (realpath(argv[0], target) == 0) 78 err(1, "%s", target); 79 80 if (subdir(target, argv[1]) || subdir(argv[1], target)) 81 errx(1, "%s (%s) and %s are not distinct paths", 82 argv[0], target, argv[1]); 83 84 args.target = target; 85 86 if (mount("union", argv[1], mntflags, &args)) 87 err(1, NULL); 88 exit(0); 89 } 90 91 int 92 subdir(p, dir) 93 const char *p; 94 const char *dir; 95 { 96 int l; 97 98 l = strlen(dir); 99 if (l <= 1) 100 return (1); 101 102 if ((strncmp(p, dir, l) == 0) && (p[l] == '/' || p[l] == '\0')) 103 return (1); 104 105 return (0); 106 } 107 108 void 109 usage() 110 { 111 (void)fprintf(stderr, 112 "usage: mount_union [-br] [-o options] target_fs mount_point\n"); 113 exit(1); 114 } 115