int main (int argc, char **argv) { int c; int err; int nomtab = 0; unsigned long flags = MS_NODEV; char *host_name; char *mount_point; struct vbsf_mount_info_new mntinf; struct vbsf_mount_opts opts = { 0, /* uid */ 0, /* gid */ 0, /* ttl */ ~0U, /* dmode */ ~0U, /* fmode*/ 0, /* dmask */ 0, /* fmask */ 0, /* ronly */ 0, /* noexec */ 0, /* nodev */ 0, /* nosuid */ 0, /* remount */ "\0", /* nls_name */ NULL, /* convertcp */ }; mntinf.nullchar = '\0'; mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0; mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1; mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2; mntinf.length = sizeof(mntinf); if (getuid()) panic("Only root can mount shared folders from the host.\n"); if (!argv[0]) argv[0] = "mount.vboxsf"; /* Compile-time assertions */ CT_ASSERT(sizeof(uid_t) == sizeof(int)); CT_ASSERT(sizeof(gid_t) == sizeof(int)); while ((c = getopt(argc, argv, "rwno:h")) != -1) { switch (c) { default: fprintf(stderr, "unknown option `%c:%#x'\n", c, c); case '?': case 'h': usage(argv[0]); case 'r': opts.ronly = 1; break; case 'w': opts.ronly = 0; case 'o': process_mount_opts(optarg, &opts); break; case 'n': nomtab = 1; break; } } if (argc - optind < 2) usage(argv[0]); host_name = argv[optind]; mount_point = argv[optind + 1]; if (opts.convertcp) convertcp(opts.convertcp, host_name, &mntinf); else { if (strlen(host_name) > MAX_HOST_NAME - 1) panic("host name is too big\n"); strcpy(mntinf.name, host_name); } if (strlen(opts.nls_name) > MAX_NLS_NAME - 1) panic("%s: the character set name for I/O is too long.\n", argv[0]); strcpy(mntinf.nls_name, opts.nls_name); if (opts.ronly) flags |= MS_RDONLY; if (opts.noexec) flags |= MS_NOEXEC; if (opts.nodev) flags |= MS_NODEV; mntinf.uid = opts.uid; mntinf.gid = opts.gid; mntinf.ttl = opts.ttl; mntinf.dmode = opts.dmode; mntinf.fmode = opts.fmode; mntinf.dmask = opts.dmask; mntinf.fmask = opts.fmask; /* * Note: When adding and/or modifying parameters of the vboxsf mounting * options you also would have to adjust VBoxServiceAutoMount.cpp * to keep this code here slick without having VbglR3. */ err = mount(NULL, mount_point, "vboxsf", flags, &mntinf); if (err == -1 && errno == EPROTO) { /* Sometimes the mount utility messes up the share name. Try to * un-mangle it again. */ char szCWD[4096]; size_t cchCWD; if (!getcwd(szCWD, sizeof(szCWD))) panic_err("%s: failed to get the current working directory", argv[0]); cchCWD = strlen(szCWD); if (!strncmp(host_name, szCWD, cchCWD)) { while (host_name[cchCWD] == '/') ++cchCWD; /* We checked before that we have enough space */ strcpy(mntinf.name, host_name + cchCWD); } err = mount(NULL, mount_point, "vboxsf", flags, &mntinf); } if (err == -1 && errno == EPROTO) { /* New mount tool with old vboxsf module? Try again using the old * vbsf_mount_info_old structure. */ struct vbsf_mount_info_old mntinf_old; memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME); memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME); mntinf_old.uid = mntinf.uid; mntinf_old.gid = mntinf.gid; mntinf_old.ttl = mntinf.ttl; err = mount(NULL, mount_point, "vboxsf", flags, &mntinf_old); } if (err) panic_err("%s: mounting failed with the error", argv[0]); if (!nomtab) { err = vbsfmount_complete(host_name, mount_point, flags, &opts); switch (err) { case 0: /* Success. */ break; case 1: panic_err("%s: Could not update mount table (failed to create memstream).", argv[0]); break; case 2: panic_err("%s: Could not open mount table for update.", argv[0]); break; case 3: /* panic_err("%s: Could not add an entry to the mount table.", argv[0]); */ break; default: panic_err("%s: Unknown error while completing mount operation: %d", argv[0], err); break; } } exit(EXIT_SUCCESS); }
static int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char *pszMountPoint, vbsf_mount_opts *pOpts) { AssertPtr(pOpts); int rc = VINF_SUCCESS; char szAlreadyMountedTo[RTPATH_MAX]; /* If a Shared Folder already is mounted but not to our desired mount point, * do an unmount first! */ if ( VBoxServiceAutoMountShareIsMounted(pszShareName, szAlreadyMountedTo, sizeof(szAlreadyMountedTo)) && RTStrICmp(pszMountPoint, szAlreadyMountedTo)) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", unmounting ...\n", pszShareName, szAlreadyMountedTo); rc = VBoxServiceAutoMountUnmount(szAlreadyMountedTo); if (RT_FAILURE(rc)) VBoxServiceError("VBoxServiceAutoMountWorker: Failed to unmount \"%s\", %s (%d)!\n", szAlreadyMountedTo, strerror(errno), errno); } if (RT_SUCCESS(rc)) rc = VBoxServiceAutoMountPrepareMountPoint(pszMountPoint, pszShareName, pOpts); if (RT_SUCCESS(rc)) { #ifdef RT_OS_SOLARIS char achOptBuf[MAX_MNTOPT_STR] = { '\0', }; int flags = 0; if (pOpts->ronly) flags |= MS_RDONLY; RTStrPrintf(achOptBuf, sizeof(achOptBuf), "uid=%d,gid=%d", pOpts->uid, pOpts->gid); int r = mount(pszShareName, pszMountPoint, flags | MS_OPTIONSTR, "vboxfs", NULL, /* char *dataptr */ 0, /* int datalen */ achOptBuf, sizeof(achOptBuf)); if (r == 0) { VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint); } else { if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */ VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n", pszShareName, pszMountPoint, strerror(errno)); } #else /* !RT_OS_SOLARIS */ unsigned long flags = MS_NODEV; const char *szOptions = { "rw" }; struct vbsf_mount_info_new mntinf; mntinf.nullchar = '\0'; mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0; mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1; mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2; mntinf.length = sizeof(mntinf); mntinf.uid = pOpts->uid; mntinf.gid = pOpts->gid; mntinf.ttl = pOpts->ttl; mntinf.dmode = pOpts->dmode; mntinf.fmode = pOpts->fmode; mntinf.dmask = pOpts->dmask; mntinf.fmask = pOpts->fmask; strcpy(mntinf.name, pszShareName); strcpy(mntinf.nls_name, "\0"); int r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf); if (r == 0) { VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint); r = vbsfmount_complete(pszShareName, pszMountPoint, flags, pOpts); switch (r) { case 0: /* Success. */ errno = 0; /* Clear all errors/warnings. */ break; case 1: VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno)); break; case 2: VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno)); break; case 3: /* VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno)); */ errno = 0; break; default: VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r); break; } } else /* r == -1, we got some error in errno. */ { if (errno == EPROTO) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Messed up share name, re-trying ...\n"); /* Sometimes the mount utility messes up the share name. Try to * un-mangle it again. */ char szCWD[4096]; size_t cchCWD; if (!getcwd(szCWD, sizeof(szCWD))) VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n"); cchCWD = strlen(szCWD); if (!strncmp(pszMountPoint, szCWD, cchCWD)) { while (pszMountPoint[cchCWD] == '/') ++cchCWD; /* We checked before that we have enough space */ strcpy(mntinf.name, pszMountPoint + cchCWD); } r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf); } if (errno == EPROTO) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Re-trying with old mounting structure ...\n"); /* New mount tool with old vboxsf module? Try again using the old * vbsf_mount_info_old structure. */ struct vbsf_mount_info_old mntinf_old; memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME); memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME); mntinf_old.uid = mntinf.uid; mntinf_old.gid = mntinf.gid; mntinf_old.ttl = mntinf.ttl; r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old); } if (r == -1) /* Was there some error from one of the tries above? */ { switch (errno) { /* If we get EINVAL here, the system already has mounted the Shared Folder to another * mount point. */ case EINVAL: VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already is mounted!\n", pszShareName); /* Ignore this error! */ break; case EBUSY: /* Ignore these errors! */ break; default: VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\": %s (%d)\n", pszShareName, pszMountPoint, strerror(errno), errno); rc = RTErrConvertFromErrno(errno); break; } } } #endif /* !RT_OS_SOLARIS */ } VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with rc=%Rrc\n", rc); return rc; }