+ if (realpath(name, mntpath) == 0) {
+ warn("%s", mntpath);
+ return (1);
+ }
+
+ name = mntpath;
+
+ if (strcmp(name, "/") == 0)
+ flags |= MNT_UPDATE;
+
+ switch (mnttype) {
+ case MOUNT_UFS:
+ if (mntopts)
+ getufsopts(mntopts, &flags);
+ if (options)
+ getufsopts(options, &flags);
+ args.fspec = spec;
+#define DEFAULT_ROOTUID -2
+ args.export.ex_root = DEFAULT_ROOTUID;
+ if (flags & MNT_RDONLY)
+ args.export.ex_flags = MNT_EXRDONLY;
+ else
+ args.export.ex_flags = 0;
+ argp = (caddr_t)&args;
+ break;
+ case MOUNT_MFS:
+ case MOUNT_NFS:
+ default:
+ argv[0] = mntname;
+ argc = 1;
+ if (flags) {
+ argv[argc++] = "-F";
+ (void)snprintf(flagval, sizeof(flagval), "%d", flags);
+ argv[argc++] = flagval;
+ }
+ if (mntopts)
+ argc += getexecopts(mntopts, &argv[argc]);
+ if (options)
+ argc += getexecopts(options, &argv[argc]);
+ argv[argc++] = spec;
+ argv[argc++] = name;
+ argv[argc++] = NULL;
+ snprintf(execname, sizeof(execname),
+ "%s/mount_%s", _PATH_EXECDIR, mntname);
+ if (verbose) {
+ (void)printf("exec: %s", execname);
+ for (i = 1; i < argc - 1; i++)
+ (void)printf(" %s", argv[i]);
+ (void)printf("\n");
+ }
+ if (debug)
+ break;
+ if (pid = vfork()) {
+ if (pid == -1) {
+ warn("vfork starting file system");
+ return (1);
+ }
+ if (waitpid(pid, &status, 0) != -1 &&
+ WIFEXITED(status) &&
+ WEXITSTATUS(status) != 0)
+ return (WEXITSTATUS(status));
+ spec = mntname;
+ goto out;
+ }
+ execv(execname, argv);
+ err(1, "cannot exec %s for %s", execname, name);
+ /* NOTREACHED */
+
+ }
+ if (!debug && mount(mnttype, name, flags, argp)) {
+ (void)fprintf(stderr, "%s on %s: ", spec, name);
+ switch (errno) {
+ case EMFILE:
+ (void)fprintf(stderr, "Mount table full.\n");
+ break;
+ case EINVAL:
+ if (flags & MNT_UPDATE)
+ (void)fprintf(stderr, "Specified device %s\n",
+ "does not match mounted device");
+ else if (mnttype == MOUNT_UFS)
+ (void)fprintf(stderr, "Bogus super block\n");
+ else
+ perror(NULL);
+ break;
+ default:
+ perror(NULL);
+ break;
+ }
+ return (1);
+ }
+
+out: if (verbose)
+ prmount(spec, name, flags);
+ return (0);